<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><div id="myscoll"></div><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>Spring注解驱动开发 | XiaoFei🥝</title><meta name="keywords" content="Spring注解驱动开发"><meta name="author" content="XiaoFei🥝"><meta name="copyright" content="XiaoFei🥝"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="ffffff"><meta name="description" content="Spring注解驱动开发">
<meta property="og:type" content="article">
<meta property="og:title" content="Spring注解驱动开发">
<meta property="og:url" content="https://www.naste.top:1024/posts/1412077587.html">
<meta property="og:site_name" content="XiaoFei🥝">
<meta property="og:description" content="Spring注解驱动开发">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://www.naste.top:9000/webp/1515952743803.webp">
<meta property="article:published_time" content="2022-06-13T10:01:02.000Z">
<meta property="article:modified_time" content="2024-04-26T09:52:18.148Z">
<meta property="article:author" content="XiaoFei🥝">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="Spring">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://www.naste.top:9000/webp/1515952743803.webp"><link rel="shortcut icon" href="/"><link rel="canonical" href="https://www.naste.top:1024/posts/1412077587"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/font-awesome/6.0.0/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.staticfile.org/fancyapps-ui/4.0.31/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"/search.json","preload":true,"languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: undefined,
  noticeOutdate: {"limitDay":365,"position":"top","messagePrev":"It has been","messageNext":"days since the last update, the content of the article may be outdated."},
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":230},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: true,
    post: true
  },
  runtime: '',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdnjs.cloudflare.com/ajax/libs/flickr-justified-gallery/2.1.2/fjGallery.min.js',
      css: 'https://cdnjs.cloudflare.com/ajax/libs/flickr-justified-gallery/2.1.2/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: true,
  isAnchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'Spring注解驱动开发',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2024-04-26 17:52:18'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', 'ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          const now = new Date()
          const hour = now.getHours()
          const isNight = hour <= 6 || hour >= 18
          if (t === undefined) isNight ? activateDarkMode() : activateLightMode()
          else if (t === 'light') activateLightMode()
          else activateDarkMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><link rel="stylesheet" href="https://cdn1.tianli0.top/npm/element-ui@2.15.6/packages/theme-chalk/lib/index.css"><style id="themeColor"></style><style id="rightSide"></style><style id="transPercent"></style><style id="blurNum"></style><style id="settingStyle"></style><span id="fps"></span><style id="defineBg"></style><style id="menu_shadow"></style><svg aria-hidden="true" style="position:absolute; overflow:hidden; width:0; height:0"><symbol id="icon-sun" viewBox="0 0 1024 1024"><path d="M960 512l-128 128v192h-192l-128 128-128-128H192v-192l-128-128 128-128V192h192l128-128 128 128h192v192z" fill="#FFD878" p-id="8420"></path><path d="M736 512a224 224 0 1 0-448 0 224 224 0 1 0 448 0z" fill="#FFE4A9" p-id="8421"></path><path d="M512 109.248L626.752 224H800v173.248L914.752 512 800 626.752V800h-173.248L512 914.752 397.248 800H224v-173.248L109.248 512 224 397.248V224h173.248L512 109.248M512 64l-128 128H192v192l-128 128 128 128v192h192l128 128 128-128h192v-192l128-128-128-128V192h-192l-128-128z" fill="#4D5152" p-id="8422"></path><path d="M512 320c105.888 0 192 86.112 192 192s-86.112 192-192 192-192-86.112-192-192 86.112-192 192-192m0-32a224 224 0 1 0 0 448 224 224 0 0 0 0-448z" fill="#4D5152" p-id="8423"></path></symbol><symbol id="icon-moon" viewBox="0 0 1024 1024"><path d="M611.370667 167.082667a445.013333 445.013333 0 0 1-38.4 161.834666 477.824 477.824 0 0 1-244.736 244.394667 445.141333 445.141333 0 0 1-161.109334 38.058667 85.077333 85.077333 0 0 0-65.066666 135.722666A462.08 462.08 0 1 0 747.093333 102.058667a85.077333 85.077333 0 0 0-135.722666 65.024z" fill="#FFB531" p-id="11345"></path><path d="M329.728 274.133333l35.157333-35.157333a21.333333 21.333333 0 1 0-30.165333-30.165333l-35.157333 35.157333-35.114667-35.157333a21.333333 21.333333 0 0 0-30.165333 30.165333l35.114666 35.157333-35.114666 35.157334a21.333333 21.333333 0 1 0 30.165333 30.165333l35.114667-35.157333 35.157333 35.157333a21.333333 21.333333 0 1 0 30.165333-30.165333z" fill="#030835" p-id="11346"></path></symbol></svg><!-- hexo injector head_end start --><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiperstyle.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-tag-plugins-plus@latest/lib/assets/font-awesome-animation.min.css" media="defer" onload="this.media='all'"><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-tag-plugins-plus@latest/lib/tag_plugins.css" media="defer" onload="this.media='all'"><script src="https://npm.elemecdn.com/hexo-butterfly-tag-plugins-plus@latest/lib/assets/carousel-touch.js"></script><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-wowjs/lib/animate.min.css" media="print" onload="this.media='screen'"><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-filter-gitcalendar/lib/gitcalendar.css" media="print" onload="this.media='all'"><!-- hexo injector head_end end --><meta name="generator" content="Hexo 6.3.0"><link rel="alternate" href="/atom.xml" title="XiaoFei🥝" type="application/atom+xml">
</head><body><div id="loading-box" onclick="document.getElementById(&quot;loading-box&quot;).classList.add(&quot;loaded&quot;)"><div class="loading-bg"><div class="loading-img"></div><div class="loading-image-dot"></div></div></div><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "" data-lazy-src="https://www.naste.top:9000/images/cat.jpg" onerror="onerror=null;src='/assets/r1.jpg'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">149</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">99</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">46</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-home"></use></svg><span class="menu_word" style="font-size:17px"> 首页</span></a></div><div class="menus_item"><a class="site-page group faa-parent animated-hover hide" href="javascript:void(0);"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon--article"></use></svg><span class="menu_word" style="font-size:17px"> 文章</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child faa-parent animated-hover" href="/archives/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-guidang1">                   </use></svg><span class="menu_word" style="font-size:17px"> 归档</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/tags/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-sekuaibiaoqian">                   </use></svg><span class="menu_word" style="font-size:17px"> 标签</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/categories/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-fenlei">                   </use></svg><span class="menu_word" style="font-size:17px"> 分类</span></a></li></ul></div><div class="menus_item"><a class="site-page group faa-parent animated-hover hide" href="javascript:void(0);"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-pinweishenghuo"></use></svg><span class="menu_word" style="font-size:17px"> 休闲</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child faa-parent animated-hover" href="/life/music/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-yinle">                   </use></svg><span class="menu_word" style="font-size:17px"> 八音盒</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/life/movies/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-dianying1">                   </use></svg><span class="menu_word" style="font-size:17px"> 影院</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/life/games/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-youxishoubing">                   </use></svg><span class="menu_word" style="font-size:17px"> 游戏</span></a></li></ul></div><div class="menus_item"><a class="site-page group faa-parent animated-hover hide" href="javascript:void(0);"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-xiangzi"></use></svg><span class="menu_word" style="font-size:17px"> 八宝箱</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child faa-parent animated-hover" href="/box/gallery/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-tubiaozhizuomoban">                   </use></svg><span class="menu_word" style="font-size:17px"> 画廊</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/box/animation/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-nvwumao">                   </use></svg><span class="menu_word" style="font-size:17px"> 动画</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/box/nav/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-zhifengche">                   </use></svg><span class="menu_word" style="font-size:17px"> 网址导航</span></a></li></ul></div><div class="menus_item"><a class="site-page group faa-parent animated-hover hide" href="javascript:void(0);"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-shejiaoxinxi"></use></svg><span class="menu_word" style="font-size:17px"> 社交</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child faa-parent animated-hover" href="/social/fcircle/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-pengyouquan">                   </use></svg><span class="menu_word" style="font-size:17px"> 朋友圈</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/comments/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-liuyan">                   </use></svg><span class="menu_word" style="font-size:17px"> 留言板</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/social/link/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-lianjie">                   </use></svg><span class="menu_word" style="font-size:17px"> 友人帐</span></a></li></ul></div><div class="menus_item"><a class="site-page group faa-parent animated-hover hide" href="javascript:void(0);"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-wangye"></use></svg><span class="menu_word" style="font-size:17px"> 网站</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child faa-parent animated-hover" href="/site/census/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon--tongjibiao">                   </use></svg><span class="menu_word" style="font-size:17px"> 网站统计</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/site/echarts/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-shujutongji1">                   </use></svg><span class="menu_word" style="font-size:17px"> 文章统计</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/site/time/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-xianxingshalou">                   </use></svg><span class="menu_word" style="font-size:17px"> 旧时光</span></a></li></ul></div><div class="menus_item"><a class="site-page group faa-parent animated-hover hide" href="javascript:void(0);"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-maoliang"></use></svg><span class="menu_word" style="font-size:17px"> 个人</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child faa-parent animated-hover" href="/personal/bb/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-qunliaotian">                   </use></svg><span class="menu_word" style="font-size:17px"> 唠叨</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/personal/love/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-love-sign">                   </use></svg><span class="menu_word" style="font-size:17px"> 恋爱小屋</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/personal/about/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-paperplane">                   </use></svg><span class="menu_word" style="font-size:17px"> 关于</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/encryption/%E6%9C%BA%E5%9C%BA/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-paperplane">                   </use></svg><span class="menu_word" style="font-size:17px"> 机场</span></a></li></ul></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">XiaoFei🥝</a></span><div id="menus"><div class="menus_items"><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-home"></use></svg><span class="menu_word" style="font-size:17px"> 首页</span></a></div><div class="menus_item"><a class="site-page group faa-parent animated-hover hide" href="javascript:void(0);"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon--article"></use></svg><span class="menu_word" style="font-size:17px"> 文章</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child faa-parent animated-hover" href="/archives/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-guidang1">                   </use></svg><span class="menu_word" style="font-size:17px"> 归档</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/tags/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-sekuaibiaoqian">                   </use></svg><span class="menu_word" style="font-size:17px"> 标签</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/categories/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-fenlei">                   </use></svg><span class="menu_word" style="font-size:17px"> 分类</span></a></li></ul></div><div class="menus_item"><a class="site-page group faa-parent animated-hover hide" href="javascript:void(0);"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-pinweishenghuo"></use></svg><span class="menu_word" style="font-size:17px"> 休闲</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child faa-parent animated-hover" href="/life/music/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-yinle">                   </use></svg><span class="menu_word" style="font-size:17px"> 八音盒</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/life/movies/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-dianying1">                   </use></svg><span class="menu_word" style="font-size:17px"> 影院</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/life/games/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-youxishoubing">                   </use></svg><span class="menu_word" style="font-size:17px"> 游戏</span></a></li></ul></div><div class="menus_item"><a class="site-page group faa-parent animated-hover hide" href="javascript:void(0);"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-xiangzi"></use></svg><span class="menu_word" style="font-size:17px"> 八宝箱</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child faa-parent animated-hover" href="/box/gallery/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-tubiaozhizuomoban">                   </use></svg><span class="menu_word" style="font-size:17px"> 画廊</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/box/animation/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-nvwumao">                   </use></svg><span class="menu_word" style="font-size:17px"> 动画</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/box/nav/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-zhifengche">                   </use></svg><span class="menu_word" style="font-size:17px"> 网址导航</span></a></li></ul></div><div class="menus_item"><a class="site-page group faa-parent animated-hover hide" href="javascript:void(0);"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-shejiaoxinxi"></use></svg><span class="menu_word" style="font-size:17px"> 社交</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child faa-parent animated-hover" href="/social/fcircle/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-pengyouquan">                   </use></svg><span class="menu_word" style="font-size:17px"> 朋友圈</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/comments/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-liuyan">                   </use></svg><span class="menu_word" style="font-size:17px"> 留言板</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/social/link/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-lianjie">                   </use></svg><span class="menu_word" style="font-size:17px"> 友人帐</span></a></li></ul></div><div class="menus_item"><a class="site-page group faa-parent animated-hover hide" href="javascript:void(0);"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-wangye"></use></svg><span class="menu_word" style="font-size:17px"> 网站</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child faa-parent animated-hover" href="/site/census/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon--tongjibiao">                   </use></svg><span class="menu_word" style="font-size:17px"> 网站统计</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/site/echarts/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-shujutongji1">                   </use></svg><span class="menu_word" style="font-size:17px"> 文章统计</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/site/time/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-xianxingshalou">                   </use></svg><span class="menu_word" style="font-size:17px"> 旧时光</span></a></li></ul></div><div class="menus_item"><a class="site-page group faa-parent animated-hover hide" href="javascript:void(0);"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-maoliang"></use></svg><span class="menu_word" style="font-size:17px"> 个人</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child faa-parent animated-hover" href="/personal/bb/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-qunliaotian">                   </use></svg><span class="menu_word" style="font-size:17px"> 唠叨</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/personal/love/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-love-sign">                   </use></svg><span class="menu_word" style="font-size:17px"> 恋爱小屋</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/personal/about/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-paperplane">                   </use></svg><span class="menu_word" style="font-size:17px"> 关于</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/encryption/%E6%9C%BA%E5%9C%BA/"><svg class="menu_icon faa-tada" aria-hidden="true" style="width:1.30em;height:1.30em;vertical-align:-0.15em;fill:currentColor;overflow:hidden;"><use xlink:href="#icon-paperplane">                   </use></svg><span class="menu_word" style="font-size:17px"> 机场</span></a></li></ul></div></div><center id="name-container"><a id="page-name" href="javascript:scrollToTop()">PAGE_NAME</a></center><div id="nav-right"><div id="search-button"><a class="search faa-parent animated-hover" title="检索站内任何你想要的信息"><svg class="faa-tada icon" style="height:24px;width:24px;fill:currentColor;position:relative;top:6px" aria-hidden="true"><use xlink:href="#icon-valentine_-search-love-find-heart"></use></svg><span> 搜索</span></a></div><a class="meihua faa-parent animated-hover" onclick="toggleWinbox()" title="美化设置-自定义你的风格" id="meihua-button"><svg class="faa-tada icon" style="height:26px;width:26px;fill:currentColor;position:relative;top:8px" aria-hidden="true"><use xlink:href="#icon-tupian1"></use></svg></a><a class="sun_moon faa-parent animated-hover" onclick="switchNightMode()" title="浅色和深色模式转换" id="nightmode-button"><svg class="faa-tada" style="height:25px;width:25px;fill:currentColor;position:relative;top:7px" viewBox="0 0 1024 1024"><use id="modeicon" xlink:href="#icon-moon">       </use></svg></a><div id="toggle-menu"><a><i class="fas fa-bars fa-fw"></i></a></div></div></div></nav><div id="post-info"><h1 class="post-title">Spring注解驱动开发</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><svg class="meta_icon post-meta-icon" style="width:30px;height:30px;position:relative;top:10px"><use xlink:href="#icon-rili"></use></svg><span class="post-meta-label">发表于 </span><time class="post-meta-date-created" datetime="2022-06-13T10:01:02.000Z" title="发表于 2022-06-13 18:01:02">2022-06-13</time><span class="post-meta-separator">|</span><svg class="meta_icon post-meta-icon" style="width:18px;height:18px;position:relative;top:5px"><use xlink:href="#icon-gengxin1"></use></svg><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2024-04-26T09:52:18.148Z" title="更新于 2024-04-26 17:52:18">2024-04-26</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><svg class="meta_icon post-meta-icon" style="width:18px;height:18px;position:relative;top:5px"><use xlink:href="#icon-biaoqian"></use></svg><a class="post-meta-categories" href="/categories/Java/">Java</a><i class="fas fa-angle-right post-meta-separator"></i><svg class="meta_icon post-meta-icon" style="width:18px;height:18px;position:relative;top:5px"><use xlink:href="#icon-biaoqian"></use></svg><a class="post-meta-categories" href="/categories/Java/Spring/">Spring</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><svg class="meta_icon post-meta-icon" style="width:25px;height:25px;position:relative;top:8px"><use xlink:href="#icon-charuword"></use></svg><span class="post-meta-label">字数总计:</span><span class="word-count">1.1w</span><span class="post-meta-separator">|</span><svg class="meta_icon post-meta-icon" style="width:20px;height:20px;position:relative;top:5px"><use xlink:href="#icon-shizhong"></use></svg><span class="post-meta-label">阅读时长:</span><span>46分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="Spring注解驱动开发"><svg class="meta_icon post-meta-icon" style="width:25px;height:25px;position:relative;top:5px"><use xlink:href="#icon-eye"></use></svg><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div><section class="main-hero-waves-area waves-area"><svg class="waves-svg" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" viewBox="0 24 150 28" preserveAspectRatio="none" shape-rendering="auto"><defs><path id="gentle-wave" d="M -160 44 c 30 0 58 -18 88 -18 s 58 18 88 18 s 58 -18 88 -18 s 58 18 88 18 v 44 h -352 Z"></path></defs><g class="parallax"><use href="#gentle-wave" x="48" y="0"></use><use href="#gentle-wave" x="48" y="3"></use><use href="#gentle-wave" x="48" y="5"></use><use href="#gentle-wave" x="48" y="7"></use></g></svg></section></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><p><a target="_blank" rel="noopener" href="https://blog.csdn.net/shawnyang2019/article/details/102568833">https://blog.csdn.net/shawnyang2019/article/details/102568833</a></p>
<h1 id="Spring注解驱动开发"><a href="#Spring注解驱动开发" class="headerlink" title="Spring注解驱动开发"></a>Spring注解驱动开发</h1><h2 id="组件注册"><a href="#组件注册" class="headerlink" title="组件注册"></a>组件注册</h2><h3 id="一、组件注册-Configuration-amp-Bean给容器中注册组件"><a href="#一、组件注册-Configuration-amp-Bean给容器中注册组件" class="headerlink" title="一、组件注册-@Configuration&amp;@Bean给容器中注册组件"></a>一、组件注册-@Configuration&amp;@Bean给容器中注册组件</h3><ul>
<li><p>环境配置</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Data</span></span><br><span class="line"><span class="meta">@AllArgsConstructor</span></span><br><span class="line"><span class="meta">@NoArgsConstructor</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> id;</span><br><span class="line">    <span class="keyword">private</span> String username;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>==<strong>@Configuration</strong>==</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Configuration</span><span class="comment">//告诉Spring这是一个配置类</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfig</span> &#123;&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>==<strong>@Bean：给容器中注册一个Bean；类型为返回值类型，id默认是是用方法名作为id</strong>==</p>
<ul>
<li><p><strong>使用方式1</strong></p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//配置类 == 配置文件</span></span><br><span class="line"><span class="meta">@Configuration</span><span class="comment">//告诉Spring这是一个配置类</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfig</span> &#123;</span><br><span class="line">    <span class="meta">@Bean</span> <span class="comment">//id默认为类的首字母小写</span></span><br><span class="line">    <span class="keyword">public</span> Person <span class="title function_">person</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Person</span>(<span class="number">1</span> , <span class="string">&quot;韩信&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">PersonTest</span> &#123;</span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test1</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">ApplicationContext</span> <span class="variable">context</span> <span class="operator">=</span> <span class="keyword">new</span> 		<span class="title class_">AnnotationConfigApplicationContext</span>(MainConfig.class);</span><br><span class="line">        </span><br><span class="line">        <span class="type">Person</span> <span class="variable">person</span> <span class="operator">=</span> context.getBean(Person.class);</span><br><span class="line">        System.out.println(person);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
</ul>
<pre><code>- **使用方式2：给配置多个bean，@Bean( &quot;bean的id值&quot; )**

    <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//配置类 == 配置文件</span></span><br><span class="line"><span class="meta">@Configuration</span><span class="comment">//告诉Spring这是一个配置类</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfig</span> &#123;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Bean(&quot;person1&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> Person <span class="title function_">person</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Person</span>(<span class="number">1</span> , <span class="string">&quot;韩信&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Bean(&quot;person2&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> Person <span class="title function_">person01</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Person</span>(<span class="number">2</span> , <span class="string">&quot;李白&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">PersonTest</span> &#123;</span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test1</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">ApplicationContext</span> <span class="variable">context</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">AnnotationConfigApplicationContext</span>(MainConfig.class);</span><br><span class="line">        <span class="type">Person</span> <span class="variable">person1</span> <span class="operator">=</span> context.getBean(<span class="string">&quot;person1&quot;</span>,Person.class);</span><br><span class="line">        <span class="type">Person</span> <span class="variable">person2</span> <span class="operator">=</span> context.getBean(<span class="string">&quot;person2&quot;</span>,Person.class);</span><br><span class="line">        System.out.println(person1);</span><br><span class="line">        System.out.println(person2);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</code></pre><h3 id="二、组件注册-ComponentScan和-ComponentScans自动扫描组件和指定扫描规则"><a href="#二、组件注册-ComponentScan和-ComponentScans自动扫描组件和指定扫描规则" class="headerlink" title="二、组件注册-@ComponentScan和@ComponentScans自动扫描组件和指定扫描规则"></a>二、组件注册-@ComponentScan和@ComponentScans自动扫描组件和指定扫描规则</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">@ComponentScan</span>：<span class="keyword">value</span> 指定要扫描的包</span><br><span class="line">excludeFilters <span class="operator">=</span> <span class="keyword">Filter</span>[]：指定排除规则，指定扫描的时候按照扫描规则排除哪些组件</span><br><span class="line">includeFilters <span class="operator">=</span> <span class="keyword">Filter</span>[]：指定要的时候需要包含安歇组件包，需要将默认的扫描规则设置为<span class="literal">false</span>（useDefaultFilters <span class="operator">=</span> <span class="literal">false</span>）</span><br></pre></td></tr></table></figure>
<ul>
<li><p>==<strong>@ComponentScan</strong>==</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//@ComponentScan：指定要扫描的包</span></span><br><span class="line"><span class="meta">@ComponentScan(value = &#123;&quot;com.hngy.lf&quot;&#125;)</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//excludeFilters：指定排除规则，填写的规则将不被扫描</span></span><br><span class="line"><span class="meta">@ComponentScan(value = &#123;&quot;com.hngy.lf&quot;&#125;, excludeFilters = &#123;</span></span><br><span class="line"><span class="meta">        @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = &#123;Controller.class&#125;)</span></span><br><span class="line"><span class="meta">&#125;)</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//includeFilters：指定要的时候需要包含安歇组件包，，需要将默认的扫描规则设置为false（useDefaultFilters = false）</span></span><br><span class="line"><span class="meta">@ComponentScan(value = &#123;&quot;com.hngy.lf&quot;&#125;, includeFilters = &#123;</span></span><br><span class="line"><span class="meta">        @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = &#123;Controller.class&#125;)</span></span><br><span class="line"><span class="meta">&#125;, useDefaultFilters = false)</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>在JDK8中==<strong>@ComponentScan</strong>==注解可以写多个，不是JDK1.8可以使用<strong>==@ComponentScans==</strong>注解</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//使用多个@ComponentScan注解</span></span><br><span class="line"><span class="meta">@ComponentScan(value = &#123;&quot;com.hngy.lf.service&quot;&#125;)</span></span><br><span class="line"><span class="meta">@ComponentScan(value = &#123;&quot;com.hngy.lf.dao&quot;&#125;)</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>不是JDK1.8可以使用<strong>==@ComponentScans==</strong>注解</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//@ComponentScans注解里面是一个@ComponentScan注解数组，可以添加多个@ComponentScan注解</span></span><br><span class="line"><span class="keyword">public</span> <span class="meta">@interface</span> ComponentScans &#123;</span><br><span class="line">	ComponentScan[] value();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//========================================使用================================================</span></span><br><span class="line"><span class="meta">@ComponentScans(&#123;</span></span><br><span class="line"><span class="meta">        @ComponentScan(value = &#123;&quot;com.hngy.lf.service&quot;&#125;) ,</span></span><br><span class="line"><span class="meta">        @ComponentScan(value = &#123;&quot;com.hngy.lf.dao&quot;&#125;)</span></span><br><span class="line"><span class="meta">&#125;)</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="三、组件注册-自定义-TypeFilter指定过滤规则"><a href="#三、组件注册-自定义-TypeFilter指定过滤规则" class="headerlink" title="三、组件注册-自定义@TypeFilter指定过滤规则"></a>三、组件注册-自定义@TypeFilter指定过滤规则</h3><p>==<strong>使用@Filter注解：需要将默认的扫描规则设置为false（useDefaultFilters = false）</strong>==</p>
<ul>
<li><strong>@ComponentScan模板，过滤规则可以填写多个</strong></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@ComponentScan</span></span><br><span class="line">        (</span><br><span class="line">                value = &#123;<span class="string">&quot;com.hngy.lf&quot;</span>&#125;,</span><br><span class="line">                excludeFilters = &#123;</span><br><span class="line">                        <span class="meta">@ComponentScan</span>.Filter(type = FilterType.ANNOTATION, classes = &#123;Service.class&#125;) ,</span><br><span class="line">                &#125;,</span><br><span class="line">                includeFilters = &#123;</span><br><span class="line">                        <span class="meta">@ComponentScan</span>.Filter(type = FilterType.ANNOTATION, classes = &#123;Controller.class&#125;) ,</span><br><span class="line">                        <span class="meta">@ComponentScan</span>.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = &#123;BookService.class&#125;) ,</span><br><span class="line">                        <span class="meta">@ComponentScan</span>.Filter(type = FilterType.CUSTOM, classes = &#123;MyTypeFilter.class&#125;) ,</span><br><span class="line">                &#125;,</span><br><span class="line">                useDefaultFilters = <span class="literal">false</span></span><br><span class="line">        )</span><br></pre></td></tr></table></figure>
<ul>
<li><strong>@ComponentScan注解中的属性</strong></li>
</ul>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">excludeFilters = Filter<span class="selector-attr">[]</span>：指定排除规则，指定扫描的时候按照扫描规则排除哪些组件</span><br><span class="line">includeFilters = Filter<span class="selector-attr">[]</span>：指定要的时候需要包含安歇组件包，需要将默认的扫描规则设置为false（useDefaultFilters = false）</span><br><span class="line">FilterType<span class="selector-class">.ANNOTATION</span> ：按照注解</span><br><span class="line">FilterType<span class="selector-class">.ASSIGNABLE_TYPE</span> ：按照给定的类型，只要是对应的类型都会被加载，子类，父类</span><br><span class="line">FilterType<span class="selector-class">.ASPECTJ</span> ：使用ASPECTJ表达式</span><br><span class="line">FilterType<span class="selector-class">.REGEX</span> ：使用正则表达式</span><br><span class="line">FilterType<span class="selector-class">.CUSTOM</span> ：自定义规则，需要实现TypeFilter接口已</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//@Filter注解可以配置多个,使用指定过滤规则需要将 ”useDefaultFilters = false“ 设置为false，否则指定的过滤规则不起作用</span></span><br><span class="line"><span class="meta">@ComponentScan(value = &#123;&quot;com.hngy.lf&quot;&#125;, includeFilters = &#123;</span></span><br><span class="line"><span class="meta">        @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = &#123;Controller.class&#125;) ,</span></span><br><span class="line"><span class="meta">        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = &#123;BookService.class&#125;) ,</span></span><br><span class="line"><span class="meta">        @ComponentScan.Filter(type = FilterType.CUSTOM, classes = &#123;MyTypeFilter.class&#125;) ,</span></span><br><span class="line"><span class="meta">&#125;, useDefaultFilters = false)</span></span><br></pre></td></tr></table></figure>
<ul>
<li><strong>使用@TypeFilter注解</strong></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//========================================配置类================================================</span></span><br><span class="line"><span class="meta">@ComponentScan(value = &#123;&quot;com.hngy.lf&quot;&#125;, includeFilters = &#123;</span></span><br><span class="line"><span class="meta">        @ComponentScan.Filter(type = FilterType.CUSTOM, classes = &#123;MyTypeFilter.class&#125;) ,&#125;, useDefaultFilters = false)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfig</span> &#123;&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//========================================实现了TypeFilter接口的实现类================================================</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MyTypeFilter</span> <span class="keyword">implements</span> <span class="title class_">TypeFilter</span> &#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> metadataReader        读取到的当前正在扫描的类的信息</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> metadataReaderFactory 可以获取到其他任何信息的</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">match</span><span class="params">(MetadataReader metadataReader , MetadataReaderFactory metadataReaderFactory)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        <span class="comment">//获取当前类注解的信息</span></span><br><span class="line">        <span class="type">AnnotationMetadata</span> <span class="variable">annotationMetadata</span> <span class="operator">=</span> metadataReader.getAnnotationMetadata();</span><br><span class="line">        </span><br><span class="line">        <span class="comment">//获取当前正在扫描的类的信息</span></span><br><span class="line">        <span class="type">ClassMetadata</span> <span class="variable">classMetadata</span> <span class="operator">=</span> metadataReader.getClassMetadata();</span><br><span class="line">        </span><br><span class="line">        <span class="comment">//这里为获取com.hngy.li包下的所有类</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">className</span> <span class="operator">=</span> classMetadata.getClassName();</span><br><span class="line">        System.out.println(<span class="string">&quot;className = &quot;</span> + className);</span><br><span class="line">        </span><br><span class="line">        <span class="comment">//获取当前类的资源信息（类的路径）</span></span><br><span class="line">        <span class="type">Resource</span> <span class="variable">resource</span> <span class="operator">=</span> metadataReader.getResource();</span><br><span class="line">        </span><br><span class="line">        <span class="comment">//指定一个规则</span></span><br><span class="line">        <span class="keyword">return</span> className.contains(<span class="string">&quot;BookService&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="四、组件注册-Scope-设置组件作用域"><a href="#四、组件注册-Scope-设置组件作用域" class="headerlink" title="四、组件注册-@Scope-设置组件作用域"></a>四、组件注册-@Scope-设置组件作用域</h3><p>Spring容器管理的bean在默认情况下是单例的，也即，一个bean只会创建一个对象，存在内置 map中，之后无论获取多少次该bean，都返回同一个对象。</p>
<p>==<strong>@Scope：设置是否为单例，Spring默认采用单例方式，减少了对象的创建，从而减少了内存的消耗。</strong>==</p>
<p>但是在实际开发中是存在多例的需求的(如购物车，用户的订单等)，Spring也提供了选项可以将bean设置为多例模式。</p>
<ul>
<li><p><strong>属性值：</strong></p>
  <figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="regexp">//</span>singleton:单实例的 ：    @Scope(<span class="string">&quot;singleton&quot;</span>)</span><br><span class="line"><span class="regexp">//</span>prototype:多实例的 ：    @Scope(<span class="string">&quot;prototype&quot;</span>)</span><br><span class="line"><span class="regexp">//</span>request:同一次请求创建一个实例 ：    @Scope(<span class="string">&quot;request&quot;</span>)</span><br><span class="line"><span class="regexp">//</span>session:同一个session创建的一个实例 ：    @Scope(<span class="string">&quot;session&quot;</span>)</span><br><span class="line"></span><br><span class="line">    &lt;!--</span><br><span class="line">        scope:</span><br><span class="line">            singleton - 单例,默认值</span><br><span class="line">                容器创建时创建对象并保存到容器内部</span><br><span class="line">                自后无论获取多少次，都是从容器内部中获取该对象返回，所以得到的将是同一个对象</span><br><span class="line">                直到容器被销毁时，对象被移除出容器</span><br><span class="line">            prototype - 多例</span><br><span class="line">                容器初始化时，不会创建多例对象，只是将多例bean信息保存</span><br><span class="line">                每次获取多例对象时，都会根据保存的bean信息创建新的对象并返回</span><br><span class="line">                且这些对象不会保存到容器内部的map中</span><br><span class="line">                对象何时被销毁完全取决于用户程序本身</span><br><span class="line">    --&gt;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p><strong>在Spring中默认为单实例（单例的，对象创建一次就不会创建了）</strong></p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//========================================配置类================================================</span></span><br><span class="line"><span class="meta">@Configuration</span><span class="comment">//告诉Spring这是一个配置类</span></span><br><span class="line"><span class="meta">@ComponentScan(value = &#123;&quot;com.hngy.lf&quot;&#125;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfig</span> &#123;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> Person <span class="title function_">person</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Person</span>(<span class="number">1</span> , <span class="string">&quot;韩信&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test1</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">ApplicationContext</span> <span class="variable">context</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">AnnotationConfigApplicationContext</span>(MainConfig.class);</span><br><span class="line">    <span class="type">Person</span> <span class="variable">person1</span> <span class="operator">=</span> context.getBean(<span class="string">&quot;person&quot;</span> , Person.class);</span><br><span class="line">    <span class="type">Person</span> <span class="variable">person2</span> <span class="operator">=</span> context.getBean(<span class="string">&quot;person&quot;</span> , Person.class);</span><br><span class="line">    System.out.println(person1 == person2); <span class="comment">///输出为 ：true</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p><strong>指定@Scope值为多例的：</strong></p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//singleton:单实例的 ：    @Scope(&quot;singleton&quot;)</span></span><br><span class="line"><span class="comment">//prototype:多实例的 ：    @Scope(&quot;prototype&quot;)</span></span><br><span class="line"><span class="comment">//request:同一次请求创建一个实例 ：    @Scope(&quot;request&quot;)</span></span><br><span class="line"><span class="comment">//session:同一个session创建的一个实例 ：    @Scope(&quot;session&quot;)</span></span><br><span class="line"><span class="meta">@Bean</span></span><br><span class="line"><span class="meta">@Scope(&quot;prototype&quot;)</span><span class="comment">//设置为多实例（多例）</span></span><br><span class="line"><span class="keyword">public</span> Person <span class="title function_">person</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Person</span>(<span class="number">1</span> , <span class="string">&quot;韩信&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test1</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">ApplicationContext</span> <span class="variable">context</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">AnnotationConfigApplicationContext</span>(MainConfig.class);</span><br><span class="line">    <span class="type">Person</span> <span class="variable">person1</span> <span class="operator">=</span> context.getBean(<span class="string">&quot;person&quot;</span> , Person.class);</span><br><span class="line">    <span class="type">Person</span> <span class="variable">person2</span> <span class="operator">=</span> context.getBean(<span class="string">&quot;person&quot;</span> , Person.class);</span><br><span class="line">    System.out.println(person1 == person2); <span class="comment">//因为设置了为多实例：输出为 ：false</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li>==<strong>注意：</strong>==<ul>
<li>==当作用域为单例的时候，IOC容器在启动<strong>（new AnnotationConfigApplicationContext(MainConfig.class)，该代码执行的时候）</strong>的时候，就会将容器中所有作用域为单例的bean的实例给创建出来；以后的每次获取，就直接从IOC容器中来获取，相当于是从map.get()的一个过程；==</li>
<li>==也就是说当bean是作用域为多例的时候，IOC容器启动的时候，就不会去创建bean的实例的，而是当我们调用getBean()<strong>（ new AnnotationConfigApplicationContext(MainConfig.class).getBean（））</strong>获取的时候去创建bean的实例；而且每次调用的时候，都会创建bean的实例；==</li>
</ul>
</li>
</ul>
<h3 id="五、组件注册-Lazy-bean-懒加载"><a href="#五、组件注册-Lazy-bean-懒加载" class="headerlink" title="五、组件注册-@Lazy-bean-懒加载"></a>五、组件注册-@Lazy-bean-懒加载</h3><p>==<strong>@Lazy注解 ：懒加载机制只对单例bean有作用，使用该注解之前相当于单例模式中的饿汉式，使用了该注解之后相当于单例模式中的懒汉式    </strong>==</p>
<p><strong>写在配置类上，表示该类下的所有Bean都为懒加载，写在单独的Bean上，只是该Bean为懒加载</strong></p>
<blockquote>
<p>懒加载机制只对单例bean有作用，<strong>对于多例bean设置懒加载没有意义</strong>。</p>
<p>懒加载只是延后了对象创建的时机，对象仍然是单例的。</p>
</blockquote>
<ul>
<li>懒加载：是专门针对于单实例的bean的<ul>
<li>单实例的bean：默认是在容器启动的时候创建对象；</li>
<li>懒加载：容器启动的时候，不创建对象，而是在第一次使用（获取）Bean的时候来创建对象，并进行初始化</li>
</ul>
</li>
</ul>
<ul>
<li><p>使用：</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Bean</span></span><br><span class="line"><span class="meta">@Lazy</span></span><br><span class="line"><span class="keyword">public</span> Person <span class="title function_">person</span><span class="params">()</span> &#123;</span><br><span class="line">    System.out.println(<span class="string">&quot;1&quot;</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Person</span>(<span class="number">1</span> , <span class="string">&quot;韩信&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>为全局配置懒加载（当需要设置的懒加载的bean过多时，不用一个个的去设置可以设置==default-lazy-init=”true”,不设置默认为false==）</p>
  <figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--========================================配置文件实现全局懒加载================================================--&gt;</span></span><br><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">default-lazy-init</span>=<span class="string">&quot;true&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="六、组件注册-Conditional-懒加载"><a href="#六、组件注册-Conditional-懒加载" class="headerlink" title="六、组件注册-@Conditional-懒加载"></a>六、组件注册-@Conditional-懒加载</h3><p>==<strong>@Conditional:是SpringBoot底层大量使用的注解，按照一定的条件来进行判断，满足条件 给容器注册bean</strong>==</p>
<p><strong>@Conditional 的这个注解还可以标注在类上，对容器中的组件进行统一设置：满足当前条件，这个类中配置的所有bean注册才能生效</strong></p>
<ul>
<li>现在下面的两个bean注册到IOC容器是要条件的：<ul>
<li>如果系统是windows，给容器注册(“bill”)</li>
<li>如果系统是linux，给容器注册(“linus”)</li>
</ul>
</li>
</ul>
<ul>
<li><p>判断是否是Windows</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 判断是否为Windows系统</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">WindowsCondition</span> <span class="keyword">implements</span> <span class="title class_">Condition</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">matches</span><span class="params">(ConditionContext context , AnnotatedTypeMetadata metadata)</span> &#123;</span><br><span class="line">        <span class="comment">//3.能获取当前环境的信息</span></span><br><span class="line">        <span class="type">Environment</span> <span class="variable">environment</span> <span class="operator">=</span> context.getEnvironment();</span><br><span class="line">        <span class="comment">//获取操作系统</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">property</span> <span class="operator">=</span> environment.getProperty(<span class="string">&quot;os.name&quot;</span>);</span><br><span class="line">        <span class="keyword">assert</span> property != <span class="literal">null</span>;</span><br><span class="line">    </span><br><span class="line">        <span class="comment">//返回property是否包含windows字符串</span></span><br><span class="line">        <span class="keyword">return</span> property.contains(<span class="string">&quot;Windows&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>判断是否是Linux</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 判断操作系统是否为Linux系统</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">LinuxCondition</span> <span class="keyword">implements</span> <span class="title class_">Condition</span> &#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * ConditionContext : 判断条件能使用的上下文(环境)</span></span><br><span class="line"><span class="comment">     * AnnotatedTypeMetadata : 注释信息</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">matches</span><span class="params">(ConditionContext context , AnnotatedTypeMetadata metadata)</span> &#123;</span><br><span class="line">        <span class="comment">//判断是否为Linux系统</span></span><br><span class="line">        <span class="comment">//1.能获取到IOC容器里面的BeanFactory</span></span><br><span class="line">        <span class="type">ConfigurableListableBeanFactory</span> <span class="variable">beanFactory</span> <span class="operator">=</span> context.getBeanFactory();</span><br><span class="line">        </span><br><span class="line">        <span class="comment">//2.获取类加载器</span></span><br><span class="line">        <span class="type">ClassLoader</span> <span class="variable">classLoader</span> <span class="operator">=</span> context.getClassLoader();</span><br><span class="line">        <span class="comment">//3.能获取当前环境的信息</span></span><br><span class="line">        <span class="type">Environment</span> <span class="variable">environment</span> <span class="operator">=</span> context.getEnvironment();</span><br><span class="line">        <span class="comment">//4.获取到bean定义的注册类</span></span><br><span class="line">        <span class="type">BeanDefinitionRegistry</span> <span class="variable">registry</span> <span class="operator">=</span> context.getRegistry();</span><br><span class="line">        </span><br><span class="line">        <span class="comment">//获取操作系统</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">property</span> <span class="operator">=</span> environment.getProperty(<span class="string">&quot;os.name&quot;</span>);</span><br><span class="line">        <span class="keyword">assert</span> property != <span class="literal">null</span>;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">//返回property是否包含linux字符串</span></span><br><span class="line">        <span class="keyword">return</span> property.contains(<span class="string">&quot;linux&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>配置类</p>
  <figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="regexp">//</span>满足当前条件，这个类中配置的所有bean注册才能生效</span><br><span class="line"><span class="regexp">//</span>在类上加入该注解</span><br><span class="line">@Conditional(&#123;WindowsCondition.class&#125;)</span><br><span class="line"></span><br><span class="line"><span class="regexp">//</span>在方法上加入该注解</span><br><span class="line"><span class="regexp">//</span>满足当前条件，这个bean注册才能生效</span><br></pre></td></tr></table></figure>
</li>
</ul>
<pre><code><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//配置类 == 配置文件</span></span><br><span class="line"><span class="meta">@Configuration</span><span class="comment">//告诉Spring这是一个配置类</span></span><br><span class="line"><span class="meta">@ComponentScan(value = &#123;&quot;com.hngy.lf&quot;&#125;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfig</span> &#123;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 现在下面的两个bean注册到IOC容器是要条件的：</span></span><br><span class="line"><span class="comment">     * 1.如果系统是windows，给容器注册(&quot;bill&quot;)</span></span><br><span class="line"><span class="comment">     * 1.如果系统是linux，给容器注册(&quot;linus&quot;)</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Conditional(&#123;WindowsCondition.class&#125;)</span></span><br><span class="line">    <span class="meta">@Bean(&quot;bill&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> Person <span class="title function_">person01</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Person</span>(<span class="number">62</span> , <span class="string">&quot;Bill Gates&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Conditional(&#123;LinuxCondition.class&#125;)</span></span><br><span class="line">    <span class="meta">@Bean(&quot;linus&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> Person <span class="title function_">person02</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Person</span>(<span class="number">48</span> , <span class="string">&quot;linus&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
</code></pre><h3 id="七、组件注册-Import-给容器中快速导入一个组件"><a href="#七、组件注册-Import-给容器中快速导入一个组件" class="headerlink" title="七、组件注册-@Import-给容器中快速导入一个组件"></a>七、组件注册-@Import-给容器中快速导入一个组件</h3><p><strong>==使用了该注解之后，相当于将该组件以Bean的形式注册到了Spring中，相当于==</strong></p>
<p><strong>而当我们使用了 @Import(Color.class)注解之后，我们可以看到IOC容器里面就有这个组件了，id默认就是这个组件的全类名：</strong></p>
<ul>
<li><p>实体类</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Data</span></span><br><span class="line"><span class="meta">@AllArgsConstructor</span></span><br><span class="line"><span class="meta">@NoArgsConstructor</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> id;</span><br><span class="line">    <span class="keyword">private</span> String username;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p><strong>使用该注解之前的：</strong></p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Configuration</span><span class="comment">//告诉Spring这是一个配置类</span></span><br><span class="line"><span class="meta">@ComponentScan(value = &#123;&quot;com.hngy.lf&quot;&#125;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfig</span> &#123;  &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//======================================测试========================================</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test2</span><span class="params">()</span> &#123;</span><br><span class="line">    Map&lt;String, Person&gt; person = context.getBeansOfType(Person.class);</span><br><span class="line">    System.out.println(person); <span class="comment">// 输出 : &#123;&#125;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p><strong>使用该注解之后：</strong></p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Configuration</span><span class="comment">//告诉Spring这是一个配置类</span></span><br><span class="line"><span class="meta">@ComponentScan(value = &#123;&quot;com.hngy.lf&quot;&#125;)</span></span><br><span class="line"><span class="meta">@Import(Person.class)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfig</span> &#123;  &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//======================================测试========================================</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test2</span><span class="params">()</span> &#123;</span><br><span class="line">    Map&lt;String, Person&gt; person = context.getBeansOfType(Person.class);</span><br><span class="line">    System.out.println(person);<span class="comment">//输出&#123;com.hngy.lf.pojo.Person=Person(id=0, username=null)&#125;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="八、组件注册-Import-使用ImportSelector"><a href="#八、组件注册-Import-使用ImportSelector" class="headerlink" title="八、组件注册-@Import-使用ImportSelector"></a>八、组件注册-@Import-使用ImportSelector</h3><p><strong>==ImportSelector是一个接口：返回需要的组件的全类名的数组；==</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">ImportSelector</span> &#123;</span><br><span class="line"></span><br><span class="line">	<span class="comment">/**</span></span><br><span class="line"><span class="comment">	 * Select and return the names of which class(es) should be imported based on</span></span><br><span class="line"><span class="comment">	 * the &#123;<span class="doctag">@link</span> AnnotationMetadata&#125; of the importing @&#123;<span class="doctag">@link</span> Configuration&#125; class.</span></span><br><span class="line"><span class="comment">	 */</span></span><br><span class="line">	String[] selectImports(AnnotationMetadata importingClassMetadata);</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>==自定义逻辑返回需要导入的组件，需要实现 ImportSelector 这个接口：==</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//自定义逻辑返回需要导入的组件</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MyImportSelector</span> <span class="keyword">implements</span> <span class="title class_">ImportSelector</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> String[] selectImports(AnnotationMetadata importingClassMetadata) &#123;</span><br><span class="line">        <span class="comment">//不要返回null，会报空指针异常</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">String</span>[<span class="number">0</span>];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>==可以这样来写：@Import({Color.class,Red.class,MyImportSelector.class})==</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="comment">//满足当前条件，这个类中配置的所有bean注册才能生效</span></span><br><span class="line"><span class="meta">@Conditional(&#123;WindowsCondition.class&#125;)</span></span><br><span class="line"><span class="comment">//快速导入组件，id默认是组件的全类名</span></span><br><span class="line"><span class="meta">@Import(&#123;MyImportSelector.class&#125;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfig2</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     *  现在下面的两个bean注册到IOC容器是要条件的：</span></span><br><span class="line"><span class="comment">     *  1.如果系统是windows，给容器注册(&quot;bill&quot;)</span></span><br><span class="line"><span class="comment">     *  1.如果系统是linux，给容器注册(&quot;linus&quot;)</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Bean(<span class="string">&quot;bill&quot;</span>)</span></span><br><span class="line">    <span class="keyword">public</span> Person person01() &#123;</span><br><span class="line">        <span class="keyword">return</span> new Person(<span class="string">&quot;Bill Gates&quot;</span>,<span class="number">62</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Conditional(&#123;LinuxCondition.class&#125;)</span></span><br><span class="line">    <span class="meta">@Bean(<span class="string">&quot;linus&quot;</span>)</span></span><br><span class="line">    <span class="keyword">public</span> Person person02() &#123;</span><br><span class="line">        <span class="keyword">return</span> new Person(<span class="string">&quot;linus&quot;</span>,<span class="number">48</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 给容器中注册组件：</span></span><br><span class="line"><span class="comment">     * 1）、扫描+组件标注注解（<span class="doctag">@Controller</span>/<span class="doctag">@Service</span>/<span class="doctag">@Repository</span>/<span class="doctag">@Component</span>）</span></span><br><span class="line"><span class="comment">     * 【局限于要求是自己写的类，如果导入的第三方没有添加这些注解，那么就注册不上了】</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * 2）、<span class="doctag">@Bean</span>[导入的第三方包里面的组件]</span></span><br><span class="line"><span class="comment">     * 3）、<span class="doctag">@Import</span>[快速的给容器中导入一个组件]</span></span><br><span class="line"><span class="comment">     *      （1）、 <span class="doctag">@Import</span>(要导入容器中的组件);容器中就会自动的注册这个组件，id默认是全类名</span></span><br><span class="line"><span class="comment">     *      （2）、 ImportSelector ：返回需要的组件的全类名的数组；</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h3 id="九、组件注册-Import-使用ImportBeanDefinitionRegistrar"><a href="#九、组件注册-Import-使用ImportBeanDefinitionRegistrar" class="headerlink" title="九、组件注册- @Import-使用ImportBeanDefinitionRegistrar"></a>九、组件注册- @Import-使用ImportBeanDefinitionRegistrar</h3><p><strong>==添加一个自定义的组件==</strong></p>
<p>==ImportBeanDefinitionRegistrar是一个接口：==</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">ImportBeanDefinitionRegistrar</span> &#123;</span><br><span class="line">	<span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">registerBeanDefinitions</span><span class="params">(</span></span><br><span class="line"><span class="params">			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>==自定义一个MyImportBeanDefinitionRegistrar类并且实现ImportBeanDefinitionRegistrar这个接口：==</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MyImportBeanDefinitionRegistrar</span> <span class="keyword">implements</span> <span class="title class_">ImportBeanDefinitionRegistrar</span> &#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * AnnotationMetadata 当前类的注解信息</span></span><br><span class="line"><span class="comment">     * BeanDefinitionRegistry BeanDefinition注册类</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * 我们把所有需要添加到容器中的bean通过BeanDefinitionRegistry里面的registerBeanDefinition方法来手动的进行注册</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">registerBeanDefinitions</span><span class="params">(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)</span> &#123;</span><br><span class="line">        <span class="comment">//判断IOC容器里面是否含有这两个组件</span></span><br><span class="line">        <span class="type">boolean</span> <span class="variable">definition</span> <span class="operator">=</span> registry.containsBeanDefinition(<span class="string">&quot;com.ldc.bean.Red&quot;</span>);</span><br><span class="line">        <span class="type">boolean</span> <span class="variable">definition2</span> <span class="operator">=</span> registry.containsBeanDefinition(<span class="string">&quot;com.ldc.bean.Blue&quot;</span>);</span><br><span class="line">        <span class="comment">//如果有的话，我就把RainBow的bean的实例给注册到IOC容器中</span></span><br><span class="line">        <span class="keyword">if</span> (definition &amp;&amp; definition2) &#123;</span><br><span class="line">            <span class="comment">//指定bean的定义信息，参数里面指定要注册的bean的类型：RainBow.class</span></span><br><span class="line">            <span class="type">RootBeanDefinition</span> <span class="variable">rootBeanDefinition</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">RootBeanDefinition</span>(RainBow.class);</span><br><span class="line">            <span class="comment">//注册一个bean，并且指定bean名</span></span><br><span class="line">            registry.registerBeanDefinition(<span class="string">&quot;rainBow&quot;</span>, rootBeanDefinition );</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="十、组件注册-使用FactoryBean注册组件"><a href="#十、组件注册-使用FactoryBean注册组件" class="headerlink" title="十、组件注册-使用FactoryBean注册组件"></a>十、组件注册-使用FactoryBean注册组件</h3><ul>
<li><p>FactoryBean：接口</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">FactoryBean</span>&lt;T&gt; &#123;</span><br><span class="line">	T <span class="title function_">getObject</span><span class="params">()</span> <span class="keyword">throws</span> Exception;</span><br><span class="line">    </span><br><span class="line">	Class&lt;?&gt; getObjectType();</span><br><span class="line">    </span><br><span class="line">	<span class="type">boolean</span> <span class="title function_">isSingleton</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>创建一个类，并且实现 FactoryBean 接口：</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建一个Spring定义的FactoryBean</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ColorFactoryBean</span> <span class="keyword">implements</span> <span class="title class_">FactoryBean</span>&lt;Color&gt; &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//返回一个Color对象，这个对象会添加到容器中</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Color <span class="title function_">getObject</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;ColorFactoryBean...getBean...&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Color</span>();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//返回的类型</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Class&lt;?&gt; getObjectType() &#123;</span><br><span class="line">        <span class="keyword">return</span> Color.class;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//控制是否为单例</span></span><br><span class="line">    <span class="comment">// true：表示的就是一个单实例，在容器中保存一份</span></span><br><span class="line">    <span class="comment">// false:多实例，每次获取都会创建一个新的bean</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isSingleton</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>这个时候，在配置类里面进行配置：可以看到表面上装配的是ColorFactoryBean这个类型，但是实际上我们装配的是Color这个bean的实例：</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="comment">//满足当前条件，这个类中配置的所有bean注册才能生效</span></span><br><span class="line"><span class="meta">@Conditional(&#123;WindowsCondition.class&#125;)</span></span><br><span class="line"><span class="comment">//快速导入组件，id默认是组件的全类名</span></span><br><span class="line"><span class="meta">@Import(&#123;Color.class,Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class&#125;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfig2</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 给容器中注册组件：</span></span><br><span class="line"><span class="comment">     * 1）、扫描+组件标注注解（<span class="doctag">@Controller</span>/<span class="doctag">@Service</span>/<span class="doctag">@Repository</span>/<span class="doctag">@Component</span>）</span></span><br><span class="line"><span class="comment">     * 【局限于要求是自己写的类，如果导入的第三方没有添加这些注解，那么就注册不上了】</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * 2）、<span class="doctag">@Bean</span>[导入的第三方包里面的组件]</span></span><br><span class="line"><span class="comment">     * 3）、<span class="doctag">@Import</span>[快速的给容器中导入一个组件]</span></span><br><span class="line"><span class="comment">     *      （1）、 <span class="doctag">@Import</span>(要导入容器中的组件);容器中就会自动的注册这个组件，id默认是全类名</span></span><br><span class="line"><span class="comment">     *      （2）、 ImportSelector ：返回需要的组件的全类名的数组；</span></span><br><span class="line"><span class="comment">     *      （3）、 ImportBeanDefinitionRegistrar : 手动注册bean到容器中</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * 4）、使用Spring提供的FactoryBean（工厂bean）</span></span><br><span class="line"><span class="comment">     *      （1）、默认获取到的是工厂bean调用getObject创建的对象</span></span><br><span class="line"><span class="comment">     *      （2）、要获取工厂bean本身，我们需要给id前面加上一个“&amp;”符号：&amp;colorFactoryBean</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> ColorFactoryBean <span class="title function_">colorFactoryBean</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ColorFactoryBean</span>();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>如果我们就想要获取这个工厂bean，我们就可以在id的前面加上一个”&amp;”符号</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test4</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">ApplicationContext</span> <span class="variable">applicationContext</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">AnnotationConfigApplicationContext</span>(MainConfig2.class);</span><br><span class="line">    printBeans(applicationContext);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//工厂bean获取的是调用getObject方法创建的对象</span></span><br><span class="line">    <span class="type">Object</span> <span class="variable">colorFactoryBean</span> <span class="operator">=</span> applicationContext.getBean(<span class="string">&quot;colorFactoryBean&quot;</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;bean的类型：&quot;</span>+colorFactoryBean.getClass());</span><br><span class="line"></span><br><span class="line">    <span class="comment">//如果我们就想要获取这个工厂bean，我们就可以在id的前面加上一个&quot;&amp;&quot;符号</span></span><br><span class="line">    <span class="type">Object</span> <span class="variable">colorFactoryBean2</span> <span class="operator">=</span> applicationContext.getBean(<span class="string">&quot;&amp;colorFactoryBean&quot;</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;bean的类型：&quot;</span>+colorFactoryBean2.getClass());</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">printBeans</span><span class="params">(ApplicationContext applicationContext)</span> &#123;</span><br><span class="line">    String[] definitionNames = applicationContext.getBeanDefinitionNames();</span><br><span class="line">    <span class="keyword">for</span> (String name : definitionNames) &#123;</span><br><span class="line">        System.out.println(name);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="生命周期"><a href="#生命周期" class="headerlink" title="生命周期"></a>生命周期</h2><ul>
<li>bean的生命周期：bean的创建-&gt;初始化-&gt;销毁的过程</li>
<li>容器管理bean的生命周期：</li>
<li>我们可以自定义初始化方法和销毁的方法：容器在bean进行到当前的生命周期的时候，来调用我们自定义的初始化方法和销毁方法<br>  构造（对象创建）：<ul>
<li>单实例：在容器启动的时候创建对象</li>
<li>多实例：在每次获取的时候来创建对象</li>
</ul>
</li>
<li>初始化方法：<ul>
<li>对象创建完成，并赋值好，调用初始化方法</li>
</ul>
</li>
<li>销毁方法：<ul>
<li>单实例的bean:在容器关闭的时候进行销毁</li>
<li>多实例的bean:容器不会管理这个bean,容器不会调用销毁的方法</li>
</ul>
</li>
</ul>
<h3 id="生命周期-Bean-指定初始化和销毁方法"><a href="#生命周期-Bean-指定初始化和销毁方法" class="headerlink" title="生命周期-@Bean-指定初始化和销毁方法"></a>生命周期-@Bean-指定初始化和销毁方法</h3><ul>
<li><p><strong>指定初始化方法和销毁方法：</strong></p>
<ul>
<li>我们可以通过@Bean(initMethod = “init”,destroyMethod = “destroy”)来指定初始化方法和销毁方法</li>
<li>相当于xml配置文件bean标签里面的 init-method=”” 和 destroy-method=”” 属性</li>
</ul>
</li>
<li><p>Person类</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> id;</span><br><span class="line">    <span class="keyword">private</span> String username;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Person</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Person ---&gt; 给IOC容器中添加Bean&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">init</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;初始化方法&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">destroy</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;销毁方法&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>配置类配置初始化方法和销毁方法</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Configuration</span><span class="comment">//告诉Spring这是一个配置类</span></span><br><span class="line"><span class="meta">@ComponentScan(value = &#123;&quot;com.hngy.lf&quot;&#125;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfig</span> &#123; </span><br><span class="line">    <span class="meta">@Bean(initMethod = &quot;init&quot; ,destroyMethod = &quot;destroy&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> Person <span class="title function_">person</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Person</span>();</span><br><span class="line">    &#125; </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>测试类</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test1</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="comment">//执行了Person类中的构造函数和初始化方法</span></span><br><span class="line">    <span class="type">AnnotationConfigApplicationContext</span> <span class="variable">context</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">AnnotationConfigApplicationContext</span>(MainConfig.class);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//执行了Person类中的销毁方法</span></span><br><span class="line">    context.close();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="生命周期-InitializingBean-和-DisposableBean"><a href="#生命周期-InitializingBean-和-DisposableBean" class="headerlink" title="生命周期-InitializingBean-和-DisposableBean"></a>生命周期-InitializingBean-和-DisposableBean</h3><p><strong>InitializingBean接口：在bean的初始化方法调用之后进行调用。DisposableBean接口：在Bean的销毁方法调用之后进行调用</strong></p>
<p><strong>通过bean实现InitializingBean（定义初始化逻辑）, DisposableBean（定义销毁逻辑）；</strong></p>
<ul>
<li><p>写一个类实现DisposableBean接口和InitializingBean</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Cat</span> <span class="keyword">implements</span> <span class="title class_">DisposableBean</span>, InitializingBean &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Cat</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Cat的构造方法&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">afterPropertiesSet</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Cat ---&gt; 初始化方法&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">destroy</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Cat ---&gt; 销毁方法&quot;</span>);</span><br><span class="line">        </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>配置类中Cat的配置方法</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Bean</span></span><br><span class="line"><span class="keyword">public</span> Cat <span class="title function_">cat</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Cat</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>测试</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test2</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">AnnotationConfigApplicationContext</span> <span class="variable">context</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">AnnotationConfigApplicationContext</span>(MainConfig.class);</span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">    Cat的构造方法</span></span><br><span class="line"><span class="comment">	Cat ---&gt; 初始化方法</span></span><br><span class="line"><span class="comment">	*/</span></span><br><span class="line">    context.close();<span class="comment">//Cat ---&gt; 销毁方法</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="生命周期-PostConstruct-amp-PreDestroy"><a href="#生命周期-PostConstruct-amp-PreDestroy" class="headerlink" title="生命周期- @PostConstruct&amp;@PreDestroy"></a>生命周期- @PostConstruct&amp;@PreDestroy</h3><ul>
<li><p><strong>可以使用JSR250规范里面定义的两个注解：只能定义在方法上的注解</strong></p>
<ul>
<li>@PostConstruct :在bean创建完成并且属性赋值完成，来执行初始化方法</li>
<li>@PreDestroy ：在容器销毁bean之前通知我们来进行清理工作</li>
</ul>
</li>
<li><p>Dog类：</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Dog</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Dog</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Dog ----&gt; 构造函数&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@PostConstruct</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">init</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Dog ---&gt; 初始化方法&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@PreDestroy</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">destroy</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Dog ---&gt; 销毁方法&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>Dog类在配置类中的配置</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Bean</span></span><br><span class="line"><span class="keyword">public</span> Dog <span class="title function_">dog</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Dog</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>测试</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test1</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">AnnotationConfigApplicationContext</span> <span class="variable">context</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">AnnotationConfigApplicationContext</span>(MainConfig.class);</span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">    Dog ----&gt; 构造函数</span></span><br><span class="line"><span class="comment">	Dog ---&gt; 初始化方法</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    context.close();<span class="comment">//Dog ---&gt; 销毁方法</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="生命周期-BeanPostProcessor-后置处理器"><a href="#生命周期-BeanPostProcessor-后置处理器" class="headerlink" title="生命周期-BeanPostProcessor-后置处理器"></a>生命周期-BeanPostProcessor-后置处理器</h3><ul>
<li><p><strong>BeanPostProcessor接口：bean的后置处理器，在bean初始化前后做一些处理工作，这个接口有两个方法：</strong></p>
<ul>
<li><p>postProcessBeforeInitialization：在初始化之前工作</p>
</li>
<li><p>postProcessAfterInitialization：在初始化之后工作</p>
</li>
<li><p>执行顺序</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">postProcessBeforeInitialization();<span class="comment">//初始化方法之前执行</span></span><br><span class="line">init();<span class="comment">//初始化方法执行</span></span><br><span class="line">postProcessAfterInitialization();<span class="comment">//初始化方法之后执行</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
</ul>
<ul>
<li><p>写一个类实现接口</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Man</span> <span class="keyword">implements</span> <span class="title class_">BeanPostProcessor</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Man</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Man ---&gt; 构造函数&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Object <span class="title function_">postProcessBeforeInitialization</span><span class="params">(Object bean , String beanName)</span> <span class="keyword">throws</span> BeansException &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;postProcessBeforeInitialization...&quot;</span> + beanName + <span class="string">&quot;=&gt;&quot;</span> + bean);</span><br><span class="line">        <span class="keyword">return</span> BeanPostProcessor.<span class="built_in">super</span>.postProcessBeforeInitialization(bean , beanName);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Object <span class="title function_">postProcessAfterInitialization</span><span class="params">(Object bean , String beanName)</span> <span class="keyword">throws</span> BeansException &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;postProcessAfterInitialization...&quot;</span> + beanName + <span class="string">&quot;=&gt;&quot;</span> + bean);</span><br><span class="line">        <span class="keyword">return</span> BeanPostProcessor.<span class="built_in">super</span>.postProcessAfterInitialization(bean , beanName);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>配置类中注册Bean</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Bean</span></span><br><span class="line"><span class="keyword">public</span> Man <span class="title function_">dog</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Man</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="生命周期-BeanPostProcessor-原理"><a href="#生命周期-BeanPostProcessor-原理" class="headerlink" title="生命周期-BeanPostProcessor-原理"></a>生命周期-BeanPostProcessor-原理</h3><h3 id="生命周期-BeanPostProcessor-在Spring底层的使用"><a href="#生命周期-BeanPostProcessor-在Spring底层的使用" class="headerlink" title="生命周期- BeanPostProcessor-在Spring底层的使用"></a>生命周期- BeanPostProcessor-在Spring底层的使用</h3><h2 id="属性赋值"><a href="#属性赋值" class="headerlink" title="属性赋值"></a>属性赋值</h2><h3 id="属性赋值-Value-赋值"><a href="#属性赋值-Value-赋值" class="headerlink" title="属性赋值-@Value-赋值"></a>属性赋值-@Value-赋值</h3><p><strong>在属性上使用@Value注解给属性赋值赋值</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Value(&quot;张三&quot;)</span></span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="meta">@Value(&quot;18&quot;)</span></span><br><span class="line">    <span class="keyword">private</span> Integer age;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//省略get和set方法</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="属性赋值-PropertySource-加载外部配置文件"><a href="#属性赋值-PropertySource-加载外部配置文件" class="headerlink" title="属性赋值- @PropertySource 加载外部配置文件"></a>属性赋值- @PropertySource 加载外部配置文件</h3><p><strong>使用@PropertySource注解加载外部配置文件，读取配置文件中的值赋给属性</strong></p>
<ul>
<li><p>==<strong>XML配置文件读取配置文件</strong>==</p>
  <figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">context:property-placeholder</span> <span class="attr">location</span>=<span class="string">&quot;classpath:person.properties&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>==<strong>注解读取配置文件：</strong>==<strong>查看源码的时候，我们可以发现，这个注解是一个可重复标注的注解，可多次标注，也可以在一个注解内添加外部配置文件位置的数组，我们也可以用PropertySources内部包含多个PropertySource ：</strong></p>
<ul>
<li><p>@PropertySources注解：</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Target(ElementType.TYPE)</span></span><br><span class="line"><span class="meta">@Retention(RetentionPolicy.RUNTIME)</span></span><br><span class="line"><span class="meta">@Documented</span></span><br><span class="line"><span class="meta">@Repeatable(PropertySources.class)</span></span><br><span class="line"><span class="keyword">public</span> <span class="meta">@interface</span> PropertySource &#123;</span><br><span class="line"></span><br><span class="line">	String <span class="title function_">name</span><span class="params">()</span> <span class="keyword">default</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line"></span><br><span class="line">	String[] value();</span><br><span class="line"></span><br><span class="line">	<span class="type">boolean</span> <span class="title function_">ignoreResourceNotFound</span><span class="params">()</span> <span class="keyword">default</span> <span class="literal">false</span>;</span><br><span class="line"></span><br><span class="line">	String <span class="title function_">encoding</span><span class="params">()</span> <span class="keyword">default</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">    </span><br><span class="line">	Class&lt;? <span class="keyword">extends</span> <span class="title class_">PropertySourceFactory</span>&gt; factory() <span class="keyword">default</span> PropertySourceFactory.class;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>@PropertySources ：内部可以指定多个@PropertySource</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Target(ElementType.TYPE)</span></span><br><span class="line"><span class="meta">@Retention(RetentionPolicy.RUNTIME)</span></span><br><span class="line"><span class="meta">@Documented</span></span><br><span class="line"><span class="keyword">public</span> <span class="meta">@interface</span> PropertySources &#123;</span><br><span class="line"></span><br><span class="line">	PropertySource[] value();</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
</ul>
<pre><code>- **在配置类中使用注解加载配置文件加载配置文件：**

    <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PropertySource(value = &#123;&quot;classpath:/jdbc.properties&quot;&#125;)</span><span class="comment">//加载配置文件</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfig</span> &#123;  &#125;</span><br></pre></td></tr></table></figure>

- 读取配置文件中的值

    <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line">    <span class="comment">//使用@Value赋值</span></span><br><span class="line">    <span class="comment">//1.基本的数值</span></span><br><span class="line">    <span class="comment">//2.可以写SpEL: #&#123;&#125;</span></span><br><span class="line">    <span class="comment">//3.可以写$&#123;&#125;：取出配置文件【properties】中的值（在运行环境变量里面的值）</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">//1.基本的数值</span></span><br><span class="line">    <span class="meta">@Value(&quot;张三&quot;)</span></span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//2.可以写SpEL: #&#123;&#125;</span></span><br><span class="line">    <span class="meta">@Value(&quot;#&#123;20-2&#125;&quot;)</span></span><br><span class="line">    <span class="keyword">private</span> Integer age;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//3.可以写$&#123;&#125;：取出配置文件【properties】中的值（在运行环境变量里面的值）</span></span><br><span class="line">    <span class="meta">@Value(&quot;$&#123;jdbc.driverClass&#125;&quot;)</span></span><br><span class="line">    <span class="keyword">private</span> String jdbcName;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</code></pre><ul>
<li>==<strong>可以用Environment里面的getProperty()方法来获取：</strong>==</li>
</ul>
<pre><code>- 配置类

    <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PropertySource(value = &#123;&quot;classpath:/jdbc.properties&quot;&#125;)</span><span class="comment">//加载配置类</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfig</span> &#123;  &#125;</span><br></pre></td></tr></table></figure>



- properties配置文件

    <figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">jdbc.username</span> = <span class="string">root</span></span><br><span class="line"><span class="attr">jdbc.password</span> = <span class="string">root</span></span><br><span class="line"><span class="attr">jdbc.driverClass</span> = <span class="string">com.mysql.cj</span></span><br></pre></td></tr></table></figure>



- 测试类

    <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">valueAnnotationTest</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">AnnotationConfigApplicationContext</span> <span class="variable">context</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">AnnotationConfigApplicationContext</span>(MainConfig.class);</span><br><span class="line">    </span><br><span class="line">    <span class="type">ConfigurableEnvironment</span> <span class="variable">environment</span> <span class="operator">=</span> context.getEnvironment();</span><br><span class="line">    </span><br><span class="line">    <span class="type">String</span> <span class="variable">username</span> <span class="operator">=</span> environment.getProperty(<span class="string">&quot;jdbc.username&quot;</span>);</span><br><span class="line">    <span class="type">String</span> <span class="variable">password</span> <span class="operator">=</span> environment.getProperty(<span class="string">&quot;jdbc.password&quot;</span>);</span><br><span class="line">    <span class="type">String</span> <span class="variable">property</span> <span class="operator">=</span> environment.getProperty(<span class="string">&quot;jdbc.driverClass&quot;</span>);</span><br><span class="line">    </span><br><span class="line">    System.out.println(<span class="string">&quot;username = &quot;</span> + username);<span class="comment">//username = root</span></span><br><span class="line">    System.out.println(<span class="string">&quot;password = &quot;</span> + password);<span class="comment">//password = root</span></span><br><span class="line">    System.out.println(<span class="string">&quot;driverClass = &quot;</span> + property);<span class="comment">//driverClass = com.mysql.cj</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</code></pre><h3 id="自动装配-Autowired-amp-Qualifier-amp-Primary"><a href="#自动装配-Autowired-amp-Qualifier-amp-Primary" class="headerlink" title="自动装配- @Autowired &amp; @Qualifier &amp; @Primary"></a>自动装配- @Autowired &amp; @Qualifier &amp; @Primary</h3><p>==<strong>@Autowired 和 @Autowired(required = false)</strong>==</p>
<ul>
<li><strong>@Autowired：自动注入</strong><ul>
<li>（1）默认优先按照类型去容器中去找对应的组件：applicationContext.getBean(BookDao.class);如果找到了则进行赋值；</li>
<li>（2）如果找到了多个相同类型的组件，再将属性的名称作为组件的id去容器中查找applicationContext.getBean(“bookDao”)</li>
<li>（3）@Qualifier(“bookDao”)：使用 @Qualifier 指定需要装配的组件的id，而不是使用属性名</li>
<li>（4）自动装配默认一定要将属性赋值好，没有就会报错，可以使用@Autowired(required = false);来设置为非必须的</li>
<li>（5）可以利用@Primary：让Spring在进行自动装配的时候，默认使用首选的bean也可以继续使用@Qualifier(“bookDao”)来明确指定需要装配的bean的名字</li>
</ul>
</li>
<li>==<strong>@Autowired &amp; @Qualifier &amp; @Primary 注解的优先级：</strong>==<ul>
<li><strong>@Autowired注解：自动装配@Autowired注解是必须要使用的。@Autowired注解是根据属性的名字来进行自动装配的，如果该类型的Bean有两个，当属性名字和两个及以上Bean都不一样的时候会报错误，这时需要使用到@Qualifier注解来直接指定自动装配的属性名，或使用@Primary注解指定该类型的Bean优先匹配@Primary注解标注的Bean</strong></li>
<li><strong>@Qualifier注解和@Autowired注解的使用：@Qualifier注解需要和@Autowired注解一起使用。@Qualifier指定装配哪个Bean之后，该属性只能装配该Bean，不能改变，@Qualifier注解的优先级比@Primary优先级高</strong></li>
<li><strong>@Primary 注解：使用@Primary 标注的Bean，属性自动装配的时候会首先匹配该注解标注的Bean，同一个类型的Bean只能有一个Bean使用该注解来标注，否则会报错误，如果非要标注两个及以上的@Primary注解，需要该类型的Bean全部都添加@Qualifier注解</strong></li>
<li>==<strong>三个注解优先级：@Qualifier（根据指定的Bean的id名） &gt; @Primary（指定Bean的优先装配） &gt; @Autowired（根据标注的属性的名称自动装配）</strong>==</li>
</ul>
</li>
</ul>
<ul>
<li>==<strong>注意：当使用自动装配的时候必须要有至少一个属性该类型的Bean，否则会报错，应为@Autowired注解中 required 属性值默认为true，所以必须要有至少一个该类型的Bean。这个时候不想给属性赋值，又想使用自动自动装配，可以使用：@Autowired(required = false)，将 required  属性的值设置为false就不会报错了。不过此属性的值为null</strong>==</li>
</ul>
<ul>
<li><p>@Qualifier注解和@Aurowired注解的使用：</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookService</span> &#123;</span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> BookDao bookDao;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Qualifier(&quot;userDao&quot;)</span></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> UserDao userdao;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>@Primary注解的使用：当没有使用@Qualifier注解实现自动装配的属性会优先使用@Primary标注的Bean</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Primary</span></span><br><span class="line"><span class="meta">@Bean(&quot;bookDao3&quot;)</span></span><br><span class="line"><span class="keyword">public</span> BookDao <span class="title function_">bookDao2</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">BookDao</span> <span class="variable">bookDao</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BookDao</span>();</span><br><span class="line">    bookDao.setLable(<span class="string">&quot;3&quot;</span>);</span><br><span class="line">    <span class="keyword">return</span> bookDao;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="自动装配-Resource-amp-Inject"><a href="#自动装配-Resource-amp-Inject" class="headerlink" title="自动装配- @Resource &amp; @Inject"></a>自动装配- @Resource &amp; @Inject</h3><p><strong>Spring还支持使用 @Resource(JSR250) 和 @Inject (JSR330)（Java中的）</strong></p>
<ul>
<li>（1）@Resource：可以和@Autowired一样实现自动的装配，默认是按照组件的名称来进行装配,没有支持@Primary<br>也没有支持和@Autowired(required = false)一样的功能</li>
<li>（2）@Inject：需要导入javax.inject的包,和@Autowired的功能一样,没有支持和@Autowired(required = false)一样的功能，支持@primary注解）</li>
</ul>
<ul>
<li><p><strong>@Resource使用：</strong></p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookService</span> &#123;</span><br><span class="line">    <span class="meta">@Resource</span></span><br><span class="line">    <span class="keyword">private</span> BookDao bookDao;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p><strong>我们也可以用@Resource注解里面的name属性来指定装配哪一个：</strong></p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookService</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Resource(name = &quot;bookDao2&quot;)</span></span><br><span class="line">    <span class="keyword">private</span> BookDao bookDao;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p><strong>@Inject的使用==（@Inject支持@primary注解）==：</strong></p>
<ul>
<li><p>导入jar包：</p>
  <figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>javax.inject<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>javax.inject<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>1<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>使用==（@Inject支持@primary注解）==：</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookService</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Inject</span></span><br><span class="line">    <span class="keyword">private</span> BookDao bookDao;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
</ul>
<h3 id="自动装配-方法、构造器位置的自动装配"><a href="#自动装配-方法、构造器位置的自动装配" class="headerlink" title="自动装配-方法、构造器位置的自动装配"></a>自动装配-方法、构造器位置的自动装配</h3><p><strong>@Autowired注解可以标注的位置：构造器，参数，方法，属性；都是从容器中来获取参数组件的值</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Target(&#123;ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE&#125;)</span></span><br><span class="line"><span class="meta">@Retention(RetentionPolicy.RUNTIME)</span></span><br><span class="line"><span class="meta">@Documented</span></span><br><span class="line"><span class="keyword">public</span> <span class="meta">@interface</span> Autowired &#123;</span><br><span class="line">	<span class="type">boolean</span> <span class="title function_">required</span><span class="params">()</span> <span class="keyword">default</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li><p><strong>@Autowired注解标注在方法上：</strong>用的最多的方式就是在@Bean注解标注的方法的参数，这个参数就是会从容器中获取，在这个方法的参数前面可以加上@Autowired注解，也可以省略，默认是不写@Autowired，都能自动装配；</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Boss</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Car car;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Autowired</span> <span class="comment">//标注在方法上，Spring容器在创建当前对象的时候，就会调用当前方法完成赋值；</span></span><br><span class="line">    <span class="comment">//方法使用的参数，自定义类型的值从IOC容器里面进行获取</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setCar</span><span class="params">(Car car)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.car = car;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>@Autowired注解标注在构造器上，默认加在IOC容器中的组件，容器启动的时候会调用无参构造器创建对象，再进行初始化赋值操作，构造器要用的组件，也都是从容器中来获取：</p>
</li>
<li><p>注意：如果组件只有一个有参的构造器，这个有参的构造器的 @Autowired注解可以省略，参数位置的组件还是可以自动从容器中获取</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//默认加在IOC容器中的组件，容器启动的时候会调用无参构造器创建对象，再进行初始化赋值操作</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Boss</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Car car;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//构造器要用的组件，也都是从容器中来获取</span></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Boss</span><span class="params">(Car car)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.car = car;</span><br><span class="line">        System.out.println(<span class="string">&quot;Boss的有参构造器&quot;</span>+car);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>@Autowired注解标注在参数上（方法中的形参）：效果是一样的</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//默认加在IOC容器中的组件，容器启动的时候会调用无参构造器创建对象，再进行初始化赋值操作</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Boss</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Car car;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//构造器要用的组件，也都是从容器中来获取</span></span><br><span class="line">    <span class="comment">//我们也可以标注在参数上效果是一样的</span></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Boss</span><span class="params">(<span class="meta">@Autowired</span> Car car)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.car = car;</span><br><span class="line">        System.out.println(<span class="string">&quot;Boss的有参构造器&quot;</span>+car);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>如果Boss这个类里面只有一个有参构造器，在构造器里面不加@Autowired注解也是可以的：</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//默认加在IOC容器中的组件，容器启动的时候会调用无参构造器创建对象，再进行初始化赋值操作</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Boss</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Car car;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//构造器要用的组件，也都是从容器中来获取</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">//我们也可以标注在参数上效果是一样的</span></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Boss</span><span class="params">(Car car)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.car = car;</span><br><span class="line">        System.out.println(<span class="string">&quot;Boss的有参构造器&quot;</span>+car);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>在配置类中传入参数进行装配（）：</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@ComponentScan(&#123;&quot;com.ldc.service&quot;,&quot;com.ldc.dao&quot;,&quot;com.ldc.controller&quot;,&quot;com.ldc.bean&quot;&#125;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfigOfAutowired</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//@Bean标注的方法创建对象的时候，方法参数的值从容器中获取</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> Color <span class="title function_">color</span><span class="params">(Car car)</span> &#123;</span><br><span class="line">        <span class="type">Color</span> <span class="variable">color</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Color</span>();</span><br><span class="line">        color.setCar(car);</span><br><span class="line">        <span class="keyword">return</span> color;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="自动装配-Aware注入Spring底层组件-amp-原理"><a href="#自动装配-Aware注入Spring底层组件-amp-原理" class="headerlink" title="自动装配-Aware注入Spring底层组件&amp;原理"></a>自动装配-Aware注入Spring底层组件&amp;原理</h3><p>自定义组件想要使用Spring容器底层的一些组件（ApplicationContext、BeanFactory…）</p>
<p>自定义组件==实现xxxAware接口==就可以实现，在创建对象的时候，会调用接口规定的方法注入相关的组件;</p>
<p>把Spring底层的一些组件注入到自定义的bean中；</p>
<p>xxxAware等这些都是利用后置处理器的机制，比如ApplicationContextAware 是通过ApplicationContextAwareProcessor来进行处理的；</p>
<ul>
<li><p>实现ApplicationContextAware 接口，里面有一个setApplicationContext方法：</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Dog</span> <span class="keyword">implements</span> <span class="title class_">ApplicationContextAware</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> ApplicationContext applicationContext;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setApplicationContext</span><span class="params">(ApplicationContext applicationContext)</span> <span class="keyword">throws</span> BeansException &#123;</span><br><span class="line">        <span class="built_in">this</span>.applicationContext = applicationContext;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>Aware 是一个总接口：</p>
<p>  <img src= "" data-lazy-src="https://www.naste.top:9000/webp/Aware%E5%AD%90%E6%8E%A5%E5%8F%A3.webp" alt="Aware子接口.webp"></p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">Aware</span> &#123; &#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>实现部分Aware的子接口，进行测试</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Red</span> <span class="keyword">implements</span> <span class="title class_">ApplicationContextAware</span>, BeanNameAware , EmbeddedValueResolverAware &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> ApplicationContext applicationContext;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setApplicationContext</span><span class="params">(ApplicationContext applicationContext)</span> <span class="keyword">throws</span> BeansException &#123;</span><br><span class="line">        <span class="comment">//如果我们后来要用，我们就用一个变量来存起来</span></span><br><span class="line">        System.out.println(<span class="string">&quot;传入的IOC容器：&quot;</span>+applicationContext);</span><br><span class="line">        <span class="built_in">this</span>.applicationContext = applicationContext;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setBeanName</span><span class="params">(String name)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;当前bean的名字：&quot;</span>+name);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setEmbeddedValueResolver</span><span class="params">(StringValueResolver resolver)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">resolveStringValue</span> <span class="operator">=</span> resolver.resolveStringValue(<span class="string">&quot;你好$&#123;os.name&#125; 我是#&#123;20*18&#125;&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;解析的字符串&quot;</span>+resolveStringValue);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="自动装配-Profile-环境搭建"><a href="#自动装配-Profile-环境搭建" class="headerlink" title="自动装配- @Profile 环境搭建"></a>自动装配- @Profile 环境搭建</h3><p>==<strong>当在不同环境可以选择链接不同的数据库：测试环境，开发环境，生产环境</strong>==</p>
<ul>
<li><p><strong>@Profile注解源码</strong></p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Target(&#123;ElementType.TYPE, ElementType.METHOD&#125;)</span></span><br><span class="line"><span class="meta">@Retention(RetentionPolicy.RUNTIME)</span></span><br><span class="line"><span class="meta">@Documented</span></span><br><span class="line"><span class="meta">@Conditional(ProfileCondition.class)</span></span><br><span class="line"><span class="keyword">public</span> <span class="meta">@interface</span> Profile &#123;</span><br><span class="line">	String[] value();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li>引入数据源：druid、mysql驱动</li>
</ul>
<ul>
<li><p>properties配置文件</p>
  <figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">jdbc.driver</span>=<span class="string">com.mysql.cj.jdbc.Driver</span></span><br><span class="line"><span class="attr">jdbc.url</span>=<span class="string">jdbc:mysql://localhost:3306/store?serverTimezone=UTC</span></span><br><span class="line"><span class="attr">jdbc.username</span>=<span class="string">root</span></span><br><span class="line"><span class="attr">jdbc.password</span>=<span class="string">root</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>这个时候，我们就可以这样来进行配置：配置类中加上@PropertySource(“classpath:配置文件路径”)：</p>
<ul>
<li><p>三种获取配置文件中的值：</p>
<ul>
<li><p>直接通过属性上面加上@Value(“${db.user}”)</p>
</li>
<li><p>在参数上面使用@Value(“${db.password}”) </p>
<p>  public DataSource dataSourceTest(@Value(“${db.password}”) String pwd)</p>
</li>
<li><p>实现EmbeddedValueResolverAware接口，在setEmbeddedValueResolver(StringValueResolver resolver)方法里面进行获取：里面使用 resolver.resolveStringValue(“${db.driverClass}”)方法解析，返回赋值给成员属性private StringValueResolver resolver;</p>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Profile:</span></span><br><span class="line"><span class="comment"> *      Spring为我们提供的可以根据当前的环境，动态的激活和切换一系列组件的功能；</span></span><br><span class="line"><span class="comment"> * 开发环境，测试环境，生产环境</span></span><br><span class="line"><span class="comment"> * 我们以切换数据源为例：</span></span><br><span class="line"><span class="comment"> * 数据源：开发环境中(用的是A数据库)、测试环境(用的是B数据库)、而生产环境（用的又是C数据库）</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@PropertySource(value = &#123;&quot;classpath:jdbc.properties&quot;&#125;)</span><span class="comment">//加载配置类</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@ComponentScan(&#123;&quot;com.hngy.value.service&quot; , &quot;com.hngy.value.controller&quot; , &quot;com.hngy.value.dao&quot;&#125;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfig</span> <span class="keyword">implements</span> <span class="title class_">EmbeddedValueResolverAware</span> &#123;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Value(&quot;$&#123;jdbc.username&#125;&quot;)</span></span><br><span class="line">    <span class="keyword">private</span> String username;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">private</span> String driverClass;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Bean(&quot;testDataSource&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> DruidDataSource <span class="title function_">dataSourceTest</span><span class="params">(<span class="meta">@Value(&quot;$&#123;jdbc.password&#125;&quot;)</span> String password)</span> &#123;</span><br><span class="line">        <span class="type">DruidDataSource</span> <span class="variable">dataSource</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DruidDataSource</span>();</span><br><span class="line">        dataSource.setUsername(username);<span class="comment">//在属性上使用@Value注解赋值</span></span><br><span class="line">        dataSource.setPassword(password);<span class="comment">//在参数上使用@Value注解赋值</span></span><br><span class="line">        dataSource.setUrl(<span class="string">&quot;jdbc:mysql://localhost:3306/store?serverTimezone=UTC&quot;</span>);<span class="comment">//直接传值</span></span><br><span class="line">        dataSource.setDriverClassName(driverClass);<span class="comment">//使用实现EmbeddedValueResolverAware接口来获取值</span></span><br><span class="line">        <span class="keyword">return</span> dataSource;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Bean(&quot;devDataSource&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> DruidDataSource <span class="title function_">dataSourceDev</span><span class="params">(<span class="meta">@Value(&quot;$&#123;jdbc.password&#125;&quot;)</span> String password)</span> &#123;</span><br><span class="line">        <span class="type">DruidDataSource</span> <span class="variable">dataSource</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DruidDataSource</span>();</span><br><span class="line">        dataSource.setUsername(username);<span class="comment">//在属性上使用@Value注解赋值</span></span><br><span class="line">        dataSource.setPassword(password);<span class="comment">//在参数上使用@Value注解赋值</span></span><br><span class="line">        dataSource.setUrl(<span class="string">&quot;jdbc:mysql://localhost:3306/store?serverTimezone=UTC&quot;</span>);<span class="comment">//直接传值</span></span><br><span class="line">        dataSource.setDriverClassName(driverClass);<span class="comment">//使用实现EmbeddedValueResolverAware接口来获取值</span></span><br><span class="line">        <span class="keyword">return</span> dataSource;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Bean(&quot;prodDataSource&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> DruidDataSource <span class="title function_">dataSourceProd</span><span class="params">(<span class="meta">@Value(&quot;$&#123;jdbc.password&#125;&quot;)</span> String password)</span> &#123;</span><br><span class="line">        <span class="type">DruidDataSource</span> <span class="variable">dataSource</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DruidDataSource</span>();</span><br><span class="line">        dataSource.setUsername(username);<span class="comment">//在属性上使用@Value注解赋值</span></span><br><span class="line">        dataSource.setPassword(password);<span class="comment">//在参数上使用@Value注解赋值</span></span><br><span class="line">        dataSource.setUrl(<span class="string">&quot;jdbc:mysql://localhost:3306/store?serverTimezone=UTC&quot;</span>);<span class="comment">//直接传值</span></span><br><span class="line">        dataSource.setDriverClassName(driverClass);<span class="comment">//使用实现EmbeddedValueResolverAware接口来获取值</span></span><br><span class="line">        <span class="keyword">return</span> dataSource;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setEmbeddedValueResolver</span><span class="params">(StringValueResolver resolver)</span> &#123;</span><br><span class="line">        driverClass = resolver.resolveStringValue(<span class="string">&quot;$&#123;jdbc.driver&#125;&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
</ul>
<h3 id="自动装配-Profile-根据环境注册bean"><a href="#自动装配-Profile-根据环境注册bean" class="headerlink" title="自动装配- @Profile 根据环境注册bean"></a>自动装配- @Profile 根据环境注册bean</h3><p>@Profile：</p>
<p>Spring为我们提供的可以根据当前的环境，动态的激活和切换一系列组件的功能；开发环境，测试环境，生产环境</p>
<p><strong>@Profile: 指定组件在哪一个环境的情况下才能被注册到容器中，不指定任何环境都能被注册这个组件</strong></p>
<ol>
<li>加了环境标识的bean，只有这个环境被激活的时候才能注册到容器中，默认是default环境，如果指定了default，那么这个bean默认会被注册到容器中</li>
<li>@Profile 写在配置类上，只有是指定的环境，整个配置类里面的所有配置才能开始生效</li>
<li>没有标注环境标识的bean，在任何环境都是加载的</li>
</ol>
<ul>
<li><p><strong>用  @Profile 注解只激活哪一个数据源：</strong></p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Target(&#123;ElementType.TYPE, ElementType.METHOD&#125;)</span></span><br><span class="line"><span class="meta">@Retention(RetentionPolicy.RUNTIME)</span></span><br><span class="line"><span class="meta">@Documented</span></span><br><span class="line"><span class="meta">@Conditional(ProfileCondition.class)</span></span><br><span class="line"><span class="keyword">public</span> <span class="meta">@interface</span> Profile &#123;</span><br><span class="line">	String[] value();</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p><strong>给数据源加上标识：</strong></p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PropertySource(value = &#123;&quot;classpath:jdbc.properties&quot;&#125;)</span><span class="comment">//加载配置类</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@ComponentScan(&#123;&quot;com.hngy.value.service&quot; , &quot;com.hngy.value.controller&quot; , &quot;com.hngy.value.dao&quot;&#125;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfig</span> <span class="keyword">implements</span> <span class="title class_">EmbeddedValueResolverAware</span> &#123;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Value(&quot;$&#123;jdbc.username&#125;&quot;)</span></span><br><span class="line">    <span class="keyword">private</span> String username;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">private</span> String driverClass;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Profile(&quot;test&quot;)</span></span><br><span class="line">    <span class="meta">@Bean(&quot;testDataSource&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> DruidDataSource <span class="title function_">dataSourceTest</span><span class="params">(<span class="meta">@Value(&quot;$&#123;jdbc.password&#125;&quot;)</span> String password)</span> &#123;</span><br><span class="line">        <span class="type">DruidDataSource</span> <span class="variable">dataSource</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DruidDataSource</span>();</span><br><span class="line">        dataSource.setUsername(username);<span class="comment">//在属性上使用@Value注解赋值</span></span><br><span class="line">        dataSource.setPassword(password);<span class="comment">//在参数上使用@Value注解赋值</span></span><br><span class="line">        dataSource.setUrl(<span class="string">&quot;jdbc:mysql://localhost:3306/store?serverTimezone=UTC&quot;</span>);<span class="comment">//直接传值</span></span><br><span class="line">        dataSource.setDriverClassName(driverClass);<span class="comment">//使用实现EmbeddedValueResolverAware接口来获取值</span></span><br><span class="line">        <span class="keyword">return</span> dataSource;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Profile(&quot;dev&quot;)</span></span><br><span class="line">    <span class="meta">@Bean(&quot;devDataSource&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> DruidDataSource <span class="title function_">dataSourceDev</span><span class="params">(<span class="meta">@Value(&quot;$&#123;jdbc.password&#125;&quot;)</span> String password)</span> &#123;</span><br><span class="line">        <span class="type">DruidDataSource</span> <span class="variable">dataSource</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DruidDataSource</span>();</span><br><span class="line">        dataSource.setUsername(username);<span class="comment">//在属性上使用@Value注解赋值</span></span><br><span class="line">        dataSource.setPassword(password);<span class="comment">//在参数上使用@Value注解赋值</span></span><br><span class="line">        dataSource.setUrl(<span class="string">&quot;jdbc:mysql://localhost:3306/store?serverTimezone=UTC&quot;</span>);<span class="comment">//直接传值</span></span><br><span class="line">        dataSource.setDriverClassName(driverClass);<span class="comment">//使用实现EmbeddedValueResolverAware接口来获取值</span></span><br><span class="line">        <span class="keyword">return</span> dataSource;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Profile(&quot;prod&quot;)</span></span><br><span class="line">    <span class="meta">@Bean(&quot;prodDataSource&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> DruidDataSource <span class="title function_">dataSourceProd</span><span class="params">(<span class="meta">@Value(&quot;$&#123;jdbc.password&#125;&quot;)</span> String password)</span> &#123;</span><br><span class="line">        <span class="type">DruidDataSource</span> <span class="variable">dataSource</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DruidDataSource</span>();</span><br><span class="line">        dataSource.setUsername(username);<span class="comment">//在属性上使用@Value注解赋值</span></span><br><span class="line">        dataSource.setPassword(password);<span class="comment">//在参数上使用@Value注解赋值</span></span><br><span class="line">        dataSource.setUrl(<span class="string">&quot;jdbc:mysql://localhost:3306/store?serverTimezone=UTC&quot;</span>);<span class="comment">//直接传值</span></span><br><span class="line">        dataSource.setDriverClassName(driverClass);<span class="comment">//使用实现EmbeddedValueResolverAware接口来获取值</span></span><br><span class="line">        <span class="keyword">return</span> dataSource;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setEmbeddedValueResolver</span><span class="params">(StringValueResolver resolver)</span> &#123;</span><br><span class="line">        driverClass = resolver.resolveStringValue(<span class="string">&quot;$&#123;jdbc.driver&#125;&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p><strong>测试：</strong></p>
<ul>
<li><p><strong>使用命令行动态参数的方式：在虚拟机参数的位置加载-Dspring.profile.active=test</strong></p>
<p>  <img src= "" data-lazy-src="https://www.naste.top:9000/webp/%E8%AE%BE%E7%BD%AE%E7%8E%AF%E5%A2%83.webp" alt="设置环境.webp"></p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//1.使用命令行动态参数的方式</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test01</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">ApplicationContext</span> <span class="variable">applicationContext</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">AnnotationConfigApplicationContext</span>(MainConfigOfProfile.class);</span><br><span class="line">    String[] beanNamesForType = applicationContext.getBeanNamesForType(DataSource.class);</span><br><span class="line">    Stream.of(beanNamesForType).forEach(System.out::println);</span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">        运行结果：</span></span><br><span class="line"><span class="comment">        testDataSource</span></span><br><span class="line"><span class="comment">        */</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
</ul>
<pre><code>- **切换到开发的环境：**

    ![image-开发环境](https://www.naste.top:9000/webp/%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83.webp)





- **利用代码的方式来实现激活某种环境，这个时候，我们在创建IOC容器的时候，必须要用无参构造器：**

    <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test01</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">AnnotationConfigApplicationContext</span> <span class="variable">applicationContext</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">AnnotationConfigApplicationContext</span>();</span><br><span class="line">    <span class="comment">//1)使用无参构造器来创建applicationContext对象</span></span><br><span class="line">    <span class="comment">//2)设置需要激活的环境</span></span><br><span class="line">    applicationContext.getEnvironment().setActiveProfiles(<span class="string">&quot;dev&quot;</span>);</span><br><span class="line">    <span class="comment">//3)加载主配置类</span></span><br><span class="line">    applicationContext.register(MainConfigOfProfile.class);</span><br><span class="line">    <span class="comment">//4)启动刷新容器</span></span><br><span class="line">    applicationContext.refresh();</span><br><span class="line"></span><br><span class="line">    String[] beanNamesForType = applicationContext.getBeanNamesForType(DataSource.class);</span><br><span class="line">    Stream.of(beanNamesForType).forEach(System.out::println);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</code></pre><ul>
<li><p><strong>@Profile 写在配置类上，只有是指定的环境，整个配置类里面的所有配置才能开始生效:</strong></p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Profile(&quot;test&quot;)</span> <span class="comment">// 将该注解写在配置类上，需要将满足该环境，该配置类下的所</span></span><br><span class="line"><span class="meta">@PropertySource(value = &#123;&quot;classpath:jdbc.properties&quot;&#125;)</span><span class="comment">//加载配置类</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@ComponentScan(&#123;&quot;com.hngy.value.service&quot; , &quot;com.hngy.value.controller&quot; , &quot;com.hngy.value.dao&quot;&#125;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfig</span> <span class="keyword">implements</span> <span class="title class_">EmbeddedValueResolverAware</span> &#123; ... &#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="IOC-小结"><a href="#IOC-小结" class="headerlink" title="IOC-小结"></a>IOC-小结</h3><p><strong>容器：</strong></p>
<ul>
<li><p>AnnotationConfigApplicationContext：</p>
<ul>
<li>配置类</li>
</ul>
</li>
<li><p>包扫描</p>
</li>
<li><p>组件添加：</p>
<ul>
<li>@ComponentScan</li>
<li><p>@Bean</p>
<ul>
<li><p>指定初始化销毁</p>
</li>
<li><p>初始化其他方式</p>
<ul>
<li>（1）InitializingBean（初始化设置值之后）</li>
<li>（2）InitializingBean（初始化设置值之后）</li>
<li>（3）JSR250：@PostConstruct、@PreDestroy</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>@Configuration</li>
<li>@Component</li>
<li>@Service</li>
<li><p>@Controller</p>
<ul>
<li>@Repository</li>
<li>@Conditional</li>
<li>@Primary</li>
<li>@Lazy</li>
<li>@Scope</li>
<li>@Import</li>
<li>ImportSelector</li>
<li>工厂模式：FactoryBean：&amp;beanName获取Factory本身</li>
</ul>
</li>
<li><p>组件赋值</p>
<ul>
<li>@Value</li>
<li>@Autowired<ul>
<li>（1）@Qualifier</li>
<li>（2）@Resources（JSR250）</li>
<li>（3）@Inject（JSR330，需要导入javax.inject）</li>
</ul>
</li>
<li>@PropertySource @PropertySources @Profile <ul>
<li>（1）Environment </li>
<li>（2）-Dspring.profiles.active=test</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li>组件注入<ul>
<li>方法参数</li>
<li>构造器注入</li>
<li>xxxAware</li>
<li>ApplicationContextAware<br>  ApplicationContextAwareProcessor</li>
</ul>
</li>
</ul>
<h2 id="AOP"><a href="#AOP" class="headerlink" title="AOP"></a>AOP</h2><p>主要把握三步：</p>
<ol>
<li>将业务逻辑组件和切面类都加入到IOC容器中，并且告诉Spring哪一个是切面类（@Aspect）</li>
<li>在切面类上的每一个通知方法标注通知注解：告诉Spring何时何地运行（写好切入点表达式）</li>
<li>开启基于注解的AOP模式：@EnableAspectJAutoProxy</li>
</ol>
<h3 id="AOP-AOP功能测试"><a href="#AOP-AOP功能测试" class="headerlink" title="AOP-AOP功能测试"></a>AOP-AOP功能测试</h3><ul>
<li><p>导入jar包</p>
  <figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-aspects<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>5.3.4<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>写一个目标类，被代理的类</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MathCalculator</span> &#123;</span><br><span class="line">    <span class="comment">//除法</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">div</span><span class="params">(<span class="type">int</span> i, <span class="type">int</span> j)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;MathCalculator...div...&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> i / j;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>配置一个切面类：该切面类是无参数的切面类，下面还有一个可以传入参数的切面类，具体使用看下面</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//告诉Spring当前类是一个切面类</span></span><br><span class="line"><span class="meta">@Aspect</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">LogAspects</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//抽取公共的切入点表达式</span></span><br><span class="line">    <span class="comment">//本类引用：pointCut()</span></span><br><span class="line">    <span class="comment">//其他的切面类要引用</span></span><br><span class="line">    <span class="meta">@Pointcut(&quot;execution(public int com.ldc.aop.MathCalculator.*(..))&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">pointCut</span><span class="params">()</span> &#123;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//@Before在目标方法之前切入：切入点表达式（指定在哪个方法切入）</span></span><br><span class="line">    <span class="meta">@Before(&quot;pointCut()&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">logStart</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;除法运行...参数列表是：&#123;&#125;&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@After(&quot;pointCut()&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">logEnd</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;除法结束...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@AfterReturning(&quot;pointCut()&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">logReturn</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;除法正常返回...运行结果为：&#123;&#125;&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@AfterThrowing(&quot;pointCut()&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">logException</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;除法异常...异常信息为：&#123;&#125;&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>再来写一个配置类 ，把上面这两个类加入到IOC容器中，并且通过==<strong>@EnableAspectJAutoProxy注解</strong>==开启基于注解的aop模式</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *  AOP:【动态代理】</span></span><br><span class="line"><span class="comment"> *      能在程序运行期间动态的将某段代码片段切入到指定的方法指定位置进行运行的编程方式；</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> *  1、导入aop模块，Spring AOP：(spring-aspects)</span></span><br><span class="line"><span class="comment"> *  2、定义一个业务逻辑类（MathCalculator），在业务逻辑运行的时候将日志进行打印（方法之前、方法运行结束、包括方法出现异常等等）</span></span><br><span class="line"><span class="comment"> *  3、定义一个日志切面类（LogAspects）：切面类里面的方法需要动态感知MathCalculator.div运行到哪里了然后执行</span></span><br><span class="line"><span class="comment"> *      切面类里面的方法就是通知方法：</span></span><br><span class="line"><span class="comment"> *      （1）前置通知（<span class="doctag">@Before</span>）：logStart，在目标方法（div）运行之前运行</span></span><br><span class="line"><span class="comment"> *      （2）后置通知（<span class="doctag">@After</span>）：logEnd，在目标方法（div）运行之前运行</span></span><br><span class="line"><span class="comment"> *      （3）返回通知（<span class="doctag">@AfterReturning</span>）：logReturn，在目标方法（div）执行返回（无论是正常返回还是异常返回）之后运行</span></span><br><span class="line"><span class="comment"> *      （4）异常通知（<span class="doctag">@AfterThrowing</span>）：logException，在目标方法（div）出现异常之后运行</span></span><br><span class="line"><span class="comment"> *      （5）环绕通知（<span class="doctag">@Around</span>）：动态代理，手动推进目标方法运行（joinPoint.procced()）</span></span><br><span class="line"><span class="comment"> *  4、给切面类的目标方法标注何时何地运行（通知注解）</span></span><br><span class="line"><span class="comment"> *  5、将切面类和业务逻辑类（目标方法所在的类）都加入到容器中；</span></span><br><span class="line"><span class="comment"> *  6、必须要告诉Spring哪一个类是切面类（只要给切面类上加上一个注解：<span class="doctag">@Aspect</span>）</span></span><br><span class="line"><span class="comment"> *  【7】、给配置类中加入<span class="doctag">@EnableAspectJAutoProxy</span>：开启基于注解的aop模式</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@EnableAspectJAutoProxy</span><span class="comment">//配置注解AOP模式</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MainConfigOfAOP</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//将业务逻辑类加入到容器中</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> MathCalculator <span class="title function_">mathCalculator</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">MathCalculator</span>();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//将切面类加入到容器中</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> LogAspects <span class="title function_">logAspects</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">LogAspects</span>();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>可以在切面里面的通知方法里面获取方法名、参数、返回值以及异常等等：</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//告诉Spring当前类是一个切面类</span></span><br><span class="line"><span class="meta">@Aspect</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">LogAspects</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//抽取公共的切入点表达式</span></span><br><span class="line">    <span class="comment">//本类引用：pointCut()</span></span><br><span class="line">    <span class="comment">//其他的切面类要引用</span></span><br><span class="line">    <span class="meta">@Pointcut(&quot;execution(public int com.ldc.aop.MathCalculator.*(..))&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">pointCut</span><span class="params">()</span> &#123;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//@Before在目标方法之前切入：切入点表达式（指定在哪个方法切入）</span></span><br><span class="line">    <span class="meta">@Before(&quot;pointCut()&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">logStart</span><span class="params">(JoinPoint joinPoint)</span> &#123;</span><br><span class="line">        System.out.println(joinPoint.getSignature().getName()+<span class="string">&quot;除法运行...参数列表是：&#123;&quot;</span>+ Arrays.asList(joinPoint.getArgs()) +<span class="string">&quot;&#125;&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@After(&quot;pointCut()&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">logEnd</span><span class="params">(JoinPoint joinPoint)</span> &#123;</span><br><span class="line">        System.out.println(joinPoint.getSignature().getName()+<span class="string">&quot;除法结束...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@AfterReturning(value = &quot;pointCut()&quot;,returning = &quot;result&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">logReturn</span><span class="params">(Object result)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;除法正常返回...运行结果为：&#123;&quot;</span>+result+<span class="string">&quot;&#125;&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">	</span><br><span class="line">	<span class="comment">//JoinPoint这个参数一定要出现在参数列表的第一位</span></span><br><span class="line">    <span class="meta">@AfterThrowing(value = &quot;pointCut()&quot;,throwing = &quot;exception&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">logException</span><span class="params">(JoinPoint joinPoint,Exception exception)</span> &#123;</span><br><span class="line">        System.out.println(joinPoint.getSignature().getName()+<span class="string">&quot;除法异常...异常信息为：&#123;&#125;&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>  ==<strong>注意：如果要写JoinPoint这个参数，那么这个参数一定要写在参数列表的第一位；</strong>==</p>
</li>
</ul>
<h2 id="声明式事务"><a href="#声明式事务" class="headerlink" title="声明式事务"></a>声明式事务</h2><h3 id="声明式事务-环境搭建"><a href="#声明式事务-环境搭建" class="headerlink" title="声明式事务-环境搭建"></a>声明式事务-环境搭建</h3><ul>
<li><p>导入相关依赖：数据源、数据库驱动、Spring-jdbc模块</p>
  <figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-context<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>5.3.4<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-aspects<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>5.3.4<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-jdbc<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>5.3.4<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>配置数据源、JdbcTemplate（Spring提供简化数据库操作的工具）操作数据</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PropertySource(&#123;&quot;classpath:dbconfig.properties&quot;&#125;)</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">TxConfig</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//数据源</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> DataSource <span class="title function_">dataSource</span><span class="params">()</span> <span class="keyword">throws</span> PropertyVetoException &#123;</span><br><span class="line">        <span class="type">ComboPooledDataSource</span> <span class="variable">dataSource</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ComboPooledDataSource</span>();</span><br><span class="line">        dataSource.setUser(<span class="string">&quot;root&quot;</span>);</span><br><span class="line">        dataSource.setPassword(<span class="string">&quot;root&quot;</span>);</span><br><span class="line">        dataSource.setDriverClass(<span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>);</span><br><span class="line">        dataSource.setJdbcUrl(<span class="string">&quot;jdbc:mysql://localhost:3306/test&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> dataSource;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> JdbcTemplate <span class="title function_">jdbcTemplate</span><span class="params">()</span> <span class="keyword">throws</span> PropertyVetoException &#123;</span><br><span class="line">        <span class="comment">//Spring会的@Configuration类会做特殊的处理：给容器中添加组件，多次调用都是从容器中找组件</span></span><br><span class="line">        <span class="type">JdbcTemplate</span> <span class="variable">jdbcTemplate</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JdbcTemplate</span>(dataSource());</span><br><span class="line">        <span class="keyword">return</span> jdbcTemplate;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>如上配置类还只是可以操作数据库，如需要开启事务，将@Transactional注解标注在类或方法上还是不行的，还需要使用，@EnableTransactionManagement 开启基于注解的事务管理功能；</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     声明式事务：</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    环境搭建：</span></span><br><span class="line"><span class="comment">        1.导入相关依赖：数据源、数据库驱动、Spring-jdbc模块</span></span><br><span class="line"><span class="comment">        2.配置数据源、JdbcTemplate（Spring提供简化数据库操作的工具）操作数据</span></span><br><span class="line"><span class="comment">        3.给方法上标注<span class="doctag">@Transactional</span>注解表示当前的方法是一个事务方法；</span></span><br><span class="line"><span class="comment">        4.<span class="doctag">@EnableTransactionManagement</span> 开启基于注解的事务管理功能；</span></span><br><span class="line"><span class="comment">        5.配置事务管理器来控制事务（必须要有这一步）</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@ComponentScan(&#123;&quot;com.ldc.tx&quot;&#125;)</span></span><br><span class="line"><span class="meta">@PropertySource(&#123;&quot;classpath:dbconfig.properties&quot;&#125;)</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@EnableTransactionManagement</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">TxConfig</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//数据源</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> DataSource <span class="title function_">dataSource</span><span class="params">()</span> <span class="keyword">throws</span> PropertyVetoException &#123;</span><br><span class="line">        <span class="type">ComboPooledDataSource</span> <span class="variable">dataSource</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ComboPooledDataSource</span>();</span><br><span class="line">        dataSource.setUser(<span class="string">&quot;root&quot;</span>);</span><br><span class="line">        dataSource.setPassword(<span class="string">&quot;12358&quot;</span>);</span><br><span class="line">        dataSource.setDriverClass(<span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>);</span><br><span class="line">        dataSource.setJdbcUrl(<span class="string">&quot;jdbc:mysql://localhost:3306/test&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> dataSource;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> JdbcTemplate <span class="title function_">jdbcTemplate</span><span class="params">()</span> <span class="keyword">throws</span> PropertyVetoException &#123;</span><br><span class="line">        <span class="comment">//Spring会的@Configuration类会做特殊的处理：给容器中添加组件，多次调用都是从容器中找组件</span></span><br><span class="line">        <span class="type">JdbcTemplate</span> <span class="variable">jdbcTemplate</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JdbcTemplate</span>(dataSource());</span><br><span class="line">        <span class="keyword">return</span> jdbcTemplate;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//注册事务管理器在容器中</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> PlatformTransactionManager <span class="title function_">transactionManager</span><span class="params">()</span> <span class="keyword">throws</span> PropertyVetoException &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">DataSourceTransactionManager</span>(dataSource());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
</article><div class="post-copyright"><div class="post-copyright__title"><span class="post-copyright-info"><h>Spring注解驱动开发</h></span></div><div class="post-copyright__type"><span class="post-copyright-info"><a href="https://www.naste.top:1024/posts/1412077587.html">https://www.naste.top:1024/posts/1412077587.html</a></span></div><div class="post-copyright-m"><div class="post-copyright-m-info"><div class="post-copyright-a"><h>作者</h><div class="post-copyright-cc-info"><h>XiaoFei🥝</h></div></div><div class="post-copyright-c"><h>发布于</h><div class="post-copyright-cc-info"><h>2022-06-13</h></div></div><div class="post-copyright-u"><h>更新于</h><div class="post-copyright-cc-info"><h>2024-04-26</h></div></div><div class="post-copyright-c"><h>许可协议</h><div class="post-copyright-cc-info"><a class="icon" rel="noopener" target="_blank" title="Creative Commons" href="https://creativecommons.org/"><i class="fab fa-creative-commons"></i></a><a rel="noopener" target="_blank" title="CC BY-NC-SA 4.0" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a></div></div></div></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/Java/"><div class="tags-punctuation"><svg class="faa-tada icon" style="height:1.1em;width:1.1em;fill:currentColor;position:relative;top:2px;margin-right:3px" aria-hidden="true"><use xlink:href="#icon-sekuaibiaoqian"></use></svg></div>Java</a><a class="post-meta__tags" href="/tags/Spring/"><div class="tags-punctuation"><svg class="faa-tada icon" style="height:1.1em;width:1.1em;fill:currentColor;position:relative;top:2px;margin-right:3px" aria-hidden="true"><use xlink:href="#icon-sekuaibiaoqian"></use></svg></div>Spring</a></div></div><link rel="stylesheet" href="/css/coin.css" media="defer" onload="this.media='all'"/><div class="post-reward"><button class="tip-button reward-button"><span class="tip-button__text">投喂作者</span><div class="coin-wrapper"><div class="coin"><div class="coin__middle"></div><div class="coin__back"></div><div class="coin__front"></div></div></div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="https://www.naste.top:9000/images/wechat.jpg" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://www.naste.top:9000/images/wechat.jpg" alt="微信"/></a><div class="post-qr-code-desc">微信</div></li><li class="reward-item"><a href="https://www.naste.top:9000/images/alipay.jpg" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://www.naste.top:9000/images/alipay.jpg" alt="支付宝"/></a><div class="post-qr-code-desc">支付宝</div></li></ul></div></button></div><audio id="coinAudio" src="https://npm.elemecdn.com/akilar-candyassets@1.0.36/audio/aowu.m4a"></audio><script defer="defer" src="/js/coin.js"></script><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/posts/2100227203.html"><img class="prev-cover" src= "" data-lazy-src="https://www.naste.top:9000/webp/1515952743791.webp" onerror="onerror=null;src='/assets/r2.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">SpringSecurity</div></div></a></div><div class="next-post pull-right"><a href="/posts/134766740.html"><img class="next-cover" src= "" data-lazy-src="https://www.naste.top:9000/webp/1515952743782.webp" onerror="onerror=null;src='/assets/r2.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">MyBatisPlus</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/posts/2176751652.html" title="Spring+SpringMVC+MyBatis"><img class="cover" src= "" data-lazy-src="https://www.naste.top:9000/webp/1671882681.webp" alt="cover"><div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> 2024-04-26</div><div class="title">Spring+SpringMVC+MyBatis</div></div></a></div><div><a href="/posts/2920256992.html" title="SpringMVC"><img class="cover" src= "" data-lazy-src="https://www.naste.top:9000/webp/1515952743781.webp" alt="cover"><div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> 2024-04-26</div><div class="title">SpringMVC</div></div></a></div><div><a href="/posts/2621695512.html" title="Java8新特性-lambda表达式"><img class="cover" src= "" data-lazy-src="https://www.naste.top:9000/webp/1669778330.webp" alt="cover"><div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> 2024-04-26</div><div class="title">Java8新特性-lambda表达式</div></div></a></div><div><a href="/posts/2414116852.html" title="JDBC"><img class="cover" src= "" data-lazy-src="https://www.naste.top:9000/webp/1515952743784.webp" alt="cover"><div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> 2024-04-26</div><div class="title">JDBC</div></div></a></div><div><a href="/posts/134766740.html" title="MyBatisPlus"><img class="cover" src= "" data-lazy-src="https://www.naste.top:9000/webp/1515952743782.webp" alt="cover"><div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> 2024-04-26</div><div class="title">MyBatisPlus</div></div></a></div><div><a href="/posts/469711973.html" title="MyBatis"><img class="cover" src= "" data-lazy-src="https://www.naste.top:9000/webp/1515952743770.jpeg" alt="cover"><div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> 2024-04-26</div><div class="title">MyBatis</div></div></a></div></div></div><hr/><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div id="twikoo-wrap"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><svg class="meta_icon" style="width:22px;height:22px;position:relative;top:5px"><use xlink:href="#icon-mulu1"></use></svg><span style="font-weight:bold">目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#Spring%E6%B3%A8%E8%A7%A3%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91"><span class="toc-text">Spring注解驱动开发</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BB%84%E4%BB%B6%E6%B3%A8%E5%86%8C"><span class="toc-text">组件注册</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%80%E3%80%81%E7%BB%84%E4%BB%B6%E6%B3%A8%E5%86%8C-Configuration-amp-Bean%E7%BB%99%E5%AE%B9%E5%99%A8%E4%B8%AD%E6%B3%A8%E5%86%8C%E7%BB%84%E4%BB%B6"><span class="toc-text">一、组件注册-@Configuration&amp;@Bean给容器中注册组件</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BA%8C%E3%80%81%E7%BB%84%E4%BB%B6%E6%B3%A8%E5%86%8C-ComponentScan%E5%92%8C-ComponentScans%E8%87%AA%E5%8A%A8%E6%89%AB%E6%8F%8F%E7%BB%84%E4%BB%B6%E5%92%8C%E6%8C%87%E5%AE%9A%E6%89%AB%E6%8F%8F%E8%A7%84%E5%88%99"><span class="toc-text">二、组件注册-@ComponentScan和@ComponentScans自动扫描组件和指定扫描规则</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%89%E3%80%81%E7%BB%84%E4%BB%B6%E6%B3%A8%E5%86%8C-%E8%87%AA%E5%AE%9A%E4%B9%89-TypeFilter%E6%8C%87%E5%AE%9A%E8%BF%87%E6%BB%A4%E8%A7%84%E5%88%99"><span class="toc-text">三、组件注册-自定义@TypeFilter指定过滤规则</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9B%9B%E3%80%81%E7%BB%84%E4%BB%B6%E6%B3%A8%E5%86%8C-Scope-%E8%AE%BE%E7%BD%AE%E7%BB%84%E4%BB%B6%E4%BD%9C%E7%94%A8%E5%9F%9F"><span class="toc-text">四、组件注册-@Scope-设置组件作用域</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BA%94%E3%80%81%E7%BB%84%E4%BB%B6%E6%B3%A8%E5%86%8C-Lazy-bean-%E6%87%92%E5%8A%A0%E8%BD%BD"><span class="toc-text">五、组件注册-@Lazy-bean-懒加载</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%AD%E3%80%81%E7%BB%84%E4%BB%B6%E6%B3%A8%E5%86%8C-Conditional-%E6%87%92%E5%8A%A0%E8%BD%BD"><span class="toc-text">六、组件注册-@Conditional-懒加载</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%83%E3%80%81%E7%BB%84%E4%BB%B6%E6%B3%A8%E5%86%8C-Import-%E7%BB%99%E5%AE%B9%E5%99%A8%E4%B8%AD%E5%BF%AB%E9%80%9F%E5%AF%BC%E5%85%A5%E4%B8%80%E4%B8%AA%E7%BB%84%E4%BB%B6"><span class="toc-text">七、组件注册-@Import-给容器中快速导入一个组件</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%AB%E3%80%81%E7%BB%84%E4%BB%B6%E6%B3%A8%E5%86%8C-Import-%E4%BD%BF%E7%94%A8ImportSelector"><span class="toc-text">八、组件注册-@Import-使用ImportSelector</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B9%9D%E3%80%81%E7%BB%84%E4%BB%B6%E6%B3%A8%E5%86%8C-Import-%E4%BD%BF%E7%94%A8ImportBeanDefinitionRegistrar"><span class="toc-text">九、组件注册- @Import-使用ImportBeanDefinitionRegistrar</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8D%81%E3%80%81%E7%BB%84%E4%BB%B6%E6%B3%A8%E5%86%8C-%E4%BD%BF%E7%94%A8FactoryBean%E6%B3%A8%E5%86%8C%E7%BB%84%E4%BB%B6"><span class="toc-text">十、组件注册-使用FactoryBean注册组件</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F"><span class="toc-text">生命周期</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F-Bean-%E6%8C%87%E5%AE%9A%E5%88%9D%E5%A7%8B%E5%8C%96%E5%92%8C%E9%94%80%E6%AF%81%E6%96%B9%E6%B3%95"><span class="toc-text">生命周期-@Bean-指定初始化和销毁方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F-InitializingBean-%E5%92%8C-DisposableBean"><span class="toc-text">生命周期-InitializingBean-和-DisposableBean</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F-PostConstruct-amp-PreDestroy"><span class="toc-text">生命周期- @PostConstruct&amp;@PreDestroy</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F-BeanPostProcessor-%E5%90%8E%E7%BD%AE%E5%A4%84%E7%90%86%E5%99%A8"><span class="toc-text">生命周期-BeanPostProcessor-后置处理器</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F-BeanPostProcessor-%E5%8E%9F%E7%90%86"><span class="toc-text">生命周期-BeanPostProcessor-原理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F-BeanPostProcessor-%E5%9C%A8Spring%E5%BA%95%E5%B1%82%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="toc-text">生命周期- BeanPostProcessor-在Spring底层的使用</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%B1%9E%E6%80%A7%E8%B5%8B%E5%80%BC"><span class="toc-text">属性赋值</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B1%9E%E6%80%A7%E8%B5%8B%E5%80%BC-Value-%E8%B5%8B%E5%80%BC"><span class="toc-text">属性赋值-@Value-赋值</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B1%9E%E6%80%A7%E8%B5%8B%E5%80%BC-PropertySource-%E5%8A%A0%E8%BD%BD%E5%A4%96%E9%83%A8%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6"><span class="toc-text">属性赋值- @PropertySource 加载外部配置文件</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D-Autowired-amp-Qualifier-amp-Primary"><span class="toc-text">自动装配- @Autowired &amp; @Qualifier &amp; @Primary</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D-Resource-amp-Inject"><span class="toc-text">自动装配- @Resource &amp; @Inject</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D-%E6%96%B9%E6%B3%95%E3%80%81%E6%9E%84%E9%80%A0%E5%99%A8%E4%BD%8D%E7%BD%AE%E7%9A%84%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="toc-text">自动装配-方法、构造器位置的自动装配</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D-Aware%E6%B3%A8%E5%85%A5Spring%E5%BA%95%E5%B1%82%E7%BB%84%E4%BB%B6-amp-%E5%8E%9F%E7%90%86"><span class="toc-text">自动装配-Aware注入Spring底层组件&amp;原理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D-Profile-%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA"><span class="toc-text">自动装配- @Profile 环境搭建</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D-Profile-%E6%A0%B9%E6%8D%AE%E7%8E%AF%E5%A2%83%E6%B3%A8%E5%86%8Cbean"><span class="toc-text">自动装配- @Profile 根据环境注册bean</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#IOC-%E5%B0%8F%E7%BB%93"><span class="toc-text">IOC-小结</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#AOP"><span class="toc-text">AOP</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#AOP-AOP%E5%8A%9F%E8%83%BD%E6%B5%8B%E8%AF%95"><span class="toc-text">AOP-AOP功能测试</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%A3%B0%E6%98%8E%E5%BC%8F%E4%BA%8B%E5%8A%A1"><span class="toc-text">声明式事务</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%A3%B0%E6%98%8E%E5%BC%8F%E4%BA%8B%E5%8A%A1-%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA"><span class="toc-text">声明式事务-环境搭建</span></a></li></ol></li></ol></li></ol></div></div></div></div></main><footer id="footer" style="background-color: transparent;"><div id="footer-wrap"><div id="ft"><div class="ft-item-1"><div class="t-top"><div class="t-t-l"><p class="ft-t t-l-t">格言🧬</p><div class="bg-ad"><div>再看看那个光点，它就在这里，这是家园，这是我们 —— 你所爱的每一个人，你认识的一个人，你听说过的每一个人，曾经有过的每一个人，都在它上面度过他们的一生✨</div><div class="btn-xz-box"><a class="btn-xz" target="_blank" rel="noopener" href="https://stellarium.org/">点击开启星辰之旅</a></div></div></div><div class="t-t-r"><p class="ft-t t-l-t">猜你想看💡</p><ul class="ft-links"><li><a href="/posts/eec9786.html">魔改指南</a><a href="/box/nav/">网址导航</a></li><li><a href="/social/link/">我的朋友</a><a href="/comments/">留点什么</a></li><li><a href="/personal/about/">关于作者</a><a href="/archives/">文章归档</a></li><li><a href="/categories/">文章分类</a><a href="/tags/">文章标签</a></li><li><a href="/box/Gallery/">我的画廊</a><a href="/personal/bb/">我的唠叨</a></li><li><a href="/site/time/">建设进程</a><a href="/site/census/">网站统计</a></li></ul></div></div></div><div class="ft-item-2"><p class="ft-t">推荐友链⌛</p><div class="ft-img-group"><div class="img-group-item"><a href="https://www.naste.top:1024/" title="XiaoFei🥝"><img src= "" data-lazy-src="https://www.naste.top:9000/images/cat.jpg" alt=""/></a></div><div class="img-group-item"><a href="javascript:void(0)" title="广告位招租"><img src= "" data-lazy-src="https://www.naste.top:9000/webp/65307a5828af6790.webp" alt=""/></a></div><div class="img-group-item"><a href="javascript:void(0)" title="广告位招租"><img src= "" data-lazy-src="https://www.naste.top:9000/webp/65307a5828af6790.webp" alt=""/></a></div><div class="img-group-item"><a href="javascript:void(0)" title="广告位招租"><img src= "" data-lazy-src="https://www.naste.top:9000/webp/65307a5828af6790.webp" alt=""/></a></div><div class="img-group-item"><a href="javascript:void(0)" title="广告位招租"><img src= "" data-lazy-src="https://www.naste.top:9000/webp/65307a5828af6790.webp" alt=""/></a></div><div class="img-group-item"><a href="javascript:void(0)" title="广告位招租"><img src= "" data-lazy-src="https://www.naste.top:9000/webp/65307a5828af6790.webp" alt=""/></a></div><div class="img-group-item"><a href="javascript:void(0)" title="广告位招租"><img src= "" data-lazy-src="https://www.naste.top:9000/webp/65307a5828af6790.webp" alt=""/></a></div><div class="img-group-item"><a href="javascript:void(0)" title="广告位招租"><img src= "" data-lazy-src="https://www.naste.top:9000/webp/65307a5828af6790.webp" alt=""/></a></div></div></div></div><div class="copyright"><span><b>&copy;2022-2024</b></span><span><b>&nbsp;&nbsp;By XiaoFei🥝</b></span></div><div id="workboard"></div><p id="ghbdages"><a class="github-badge" target="_blank" href="https://hexo.io/" style="margin-inline:5px" title="博客框架为Hexo_v6.3.0"><img src= "" data-lazy-src="https://static.naste.top:1024/svg/blog/Frame-Hexo-blue.svg" alt=""/></a><a class="github-badge" target="_blank" href="https://butterfly.js.org/" style="margin-inline:5px" title="主题版本Butterfly_v4.3.1"><img src= "" data-lazy-src="https://static.naste.top:1024/svg/blog/Theme-Butterfly-6513df.svg" alt=""/></a><a class="github-badge" target="_blank" href="https://vercel.com/" style="margin-inline:5px" title="本站采用多线部署，主线路托管于Vercel"><img src= "" data-lazy-src="https://static.naste.top:1024/svg/blog/Hosted-Vercel-brightgreen.svg" alt=""/></a><a class="github-badge" target="_blank" href="https://user.51.la/" style="margin-inline:5px" title="本站数据分析得益于51la技术支持"><img src= "" data-lazy-src="https://static.naste.top:1024/svg/blog/Analytics-51la-3db1eb.svg" alt=""/></a><a class="github-badge" target="_blank" href="https://github.com/" style="margin-inline:5px" title="本网站源码由Github提供存储仓库"><img src= "" data-lazy-src=" https://static.naste.top:1024/svg/blog/Source-Github-d021d6.svg" alt=""/></a></p></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><a class="icon-V hidden" onclick="switchNightMode()" title="浅色和深色模式转换"><svg width="25" height="25" viewBox="0 0 1024 1024"><use id="modeicon" xlink:href="#icon-moon"></use></svg></a><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button><button class="share" type="button" title="右键模式" onclick="changeMouseMode()"><i class="fas fa-mouse"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog right_side"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button class="share" type="button" title="分享链接" onclick="share()"><i class="fas fa-share-nodes"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fas fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i><span id="percent">0<span>%</span></span></button><button id="go-down" type="button" title="直达底部" onclick="btf.scrollToDest(document.body.scrollHeight, 500)"><i class="fas fa-arrow-down"></i></button></div></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div></div></div><div id="search-mask"></div></div><div class="js-pjax" id="rightMenu"><div class="rightMenu-group rightMenu-small"><a class="rightMenu-item" href="javascript:window.history.back();"><i class="fa fa-arrow-left"></i></a><a class="rightMenu-item" href="javascript:window.history.forward();"><i class="fa fa-arrow-right"></i></a><a class="rightMenu-item" href="javascript:window.location.reload();"><i class="fa fa-refresh"></i></a><a class="rightMenu-item" href="javascript:rmf.scrollToTop();"><i class="fa fa-arrow-up"></i></a></div><div class="rightMenu-group rightMenu-line hide" id="menu-text"><a class="rightMenu-item" href="javascript:rmf.copySelect();"><i class="fa fa-copy"></i><span>复制</span></a><a class="rightMenu-item" href="javascript:window.open(&quot;https://www.baidu.com/s?wd=&quot;+window.getSelection().toString());window.location.reload();"><i class="fa fa-search"></i><span>百度搜索</span></a></div><div class="rightMenu-group rightMenu-line hide" id="menu-too"><a class="rightMenu-item" href="javascript:window.open(window.getSelection().toString());window.location.reload();"><i class="fa fa-link"></i><span>转到链接</span></a></div><div class="rightMenu-group rightMenu-line hide" id="menu-paste"><a class="rightMenu-item" href="javascript:rmf.paste()"><i class="fa fa-copy"></i><span>粘贴</span></a></div><div class="rightMenu-group rightMenu-line hide" id="menu-post"><a class="rightMenu-item" href="#post-comment"><i class="fas fa-comment"></i><span>空降评论</span></a><a class="rightMenu-item" href="javascript:rmf.copyWordsLink()"><i class="fa fa-link"></i><span>复制本文地址</span></a></div><div class="rightMenu-group rightMenu-line hide" id="menu-to"><a class="rightMenu-item" href="javascript:rmf.openWithNewTab()"><i class="fa fa-window-restore"></i><span>新窗口打开</span></a><a class="rightMenu-item" id="menu-too" href="javascript:rmf.open()"><i class="fa fa-link"></i><span>转到链接</span></a><a class="rightMenu-item" href="javascript:rmf.copyLink()"><i class="fa fa-copy"></i><span>复制链接</span></a></div><div class="rightMenu-group rightMenu-line hide" id="menu-img"><a class="rightMenu-item" href="javascript:rmf.saveAs()"><i class="fa fa-download"></i><span>保存图片</span></a><a class="rightMenu-item" href="javascript:rmf.openWithNewTab()"><i class="fa fa-window-restore"></i><span>在新窗口打开</span></a><a class="rightMenu-item" href="javascript:rmf.copyLink()"><i class="fa fa-copy"></i><span>复制图片链接</span></a></div><div class="rightMenu-group rightMenu-line"><a class="rightMenu-item" href="javascript:randomPost()"><i class="fa fa-paper-plane"></i><span>随便逛逛</span></a><a class="rightMenu-item" href="javascript:switchNightMode();"><i class="fa fa-moon"></i><span>昼夜切换</span></a><a class="rightMenu-item" href="/personal/about/"><i class="fa fa-info-circle"></i><span>关于博客</span></a><a class="rightMenu-item" href="javascript:toggleWinbox();"><i class="fas fa-cog"></i><span>美化设置</span></a><a class="rightMenu-item" href="javascript:rmf.fullScreen();"><i class="fas fa-expand"></i><span>切换全屏</span></a><a class="rightMenu-item" href="javascript:window.print();"><i class="fa-solid fa-print"></i><span>打印页面</span></a></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="https://cdn.staticfile.org/fancyapps-ui/4.0.31/fancybox.umd.min.js"></script><script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/instant.page/5.1.0/instantpage.min.js" type="module"></script><script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/vanilla-lazyload/17.3.1/lazyload.iife.min.js"></script><script>function panguFn () {
  if (typeof pangu === 'object') pangu.autoSpacingPage()
  else {
    getScript('https://cdnjs.cloudflare.com/ajax/libs/pangu/4.0.7/pangu.min.js')
      .then(() => {
        pangu.autoSpacingPage()
      })
  }
}

function panguInit () {
  if (true){
    GLOBAL_CONFIG_SITE.isPost && panguFn()
  } else {
    panguFn()
  }
}

document.addEventListener('DOMContentLoaded', panguInit)</script><script src="/js/search/local-search.js"></script><script async="async">var preloader = {
  endLoading: () => {
    document.body.style.overflow = 'auto';
    document.getElementById('loading-box').classList.add("loaded")
  },
  initLoading: () => {
    document.body.style.overflow = '';
    document.getElementById('loading-box').classList.remove("loaded")

  }
}
window.addEventListener('load',preloader.endLoading())
setTimeout(function(){preloader.endLoading();}, 5000);
document.getElementById('loading-box').addEventListener('click',()=> {preloader.endLoading()})</script><div class="js-pjax"><script>(()=>{
  const init = () => {
    twikoo.init(Object.assign({
      el: '#twikoo-wrap',
      envId: '',
      region: '',
      onCommentLoaded: function () {
        btf.loadLightbox(document.querySelectorAll('#twikoo .tk-content img:not(.tk-owo-emotion)'))
      }
    }, null))
  }

  const getCount = () => {
    const countELement = document.getElementById('twikoo-count')
    if(!countELement) return
    twikoo.getCommentsCount({
      envId: '',
      region: '',
      urls: [window.location.pathname],
      includeReply: false
    }).then(function (res) {
      countELement.innerText = res[0].count
    }).catch(function (err) {
      console.error(err);
    });
  }

  const runFn = () => {
    init()
    
  }

  const loadTwikoo = () => {
    if (typeof twikoo === 'object') {
      setTimeout(runFn,0)
      return
    } 
    getScript('https://cdn.staticfile.org/twikoo/1.6.8/twikoo.all.min.js').then(runFn)
  }

  if ('Twikoo' === 'Twikoo' || !true) {
    if (true) btf.loadComment(document.getElementById('twikoo-wrap'), loadTwikoo)
    else loadTwikoo()
  } else {
    window.loadOtherComment = () => {
      loadTwikoo()
    }
  }
})()</script></div><script src="https://cdn.staticfile.org/jquery/3.6.3/jquery.min.js"></script><script async src="https://cdn1.tianli0.top/npm/vue@2.6.14/dist/vue.min.js"></script><script async src="https://cdn1.tianli0.top/npm/element-ui@2.15.6/lib/index.js"></script><script async src="https://cdn.bootcdn.net/ajax/libs/clipboard.js/2.0.11/clipboard.min.js"></script><script defer type="text/javascript" src="https://cdn1.tianli0.top/npm/sweetalert2@8.19.0/dist/sweetalert2.all.js"></script><script async src="//npm.elemecdn.com/pace-js@1.2.4/pace.min.js"></script><script defer src="https://cdn1.tianli0.top/gh/nextapps-de/winbox/dist/winbox.bundle.min.js"></script><script async src="//at.alicdn.com/t/c/font_3586335_hsivh70x0fm.js"></script><script async src="//at.alicdn.com/t/c/font_3636804_gr02jmjr3y9.js"></script><script async src="//at.alicdn.com/t/c/font_3612150_kfv55xn3u2g.js"></script><script async src="https://cdn.wpon.cn/2022-sucai/Gold-ingot.js"></script><canvas id="universe"></canvas><canvas id="snow"></canvas><script defer src="/js/fomal.js"></script><link rel="stylesheet" href="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/aplayer/1.10.1/APlayer.min.css" media="print" onload="this.media='all'"><script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/aplayer/1.10.1/APlayer.min.js"></script><script src="https://cdn1.tianli0.top/npm/js-heo@1.0.12/metingjs/Meting.min.js"></script><script src="https://lib.baomitu.com/pjax/0.2.8/pjax.min.js"></script><script>let pjaxSelectors = ["head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show","#web_bg",".js-pjax","#bibi","body > title","#app","#tag-echarts","#posts-echart","#categories-echarts"]

var pjax = new Pjax({
  elements: 'a:not([target="_blank"])',
  selectors: pjaxSelectors,
  cacheBust: false,
  analytics: false,
  scrollRestoration: false
})

document.addEventListener('pjax:send', function () {

  // removeEventListener scroll 
  window.tocScrollFn && window.removeEventListener('scroll', window.tocScrollFn)
  window.scrollCollect && window.removeEventListener('scroll', scrollCollect)

  typeof preloader === 'object' && preloader.initLoading()
  document.getElementById('rightside').style.cssText = "opacity: ''; transform: ''"
  
  if (window.aplayers) {
    for (let i = 0; i < window.aplayers.length; i++) {
      if (!window.aplayers[i].options.fixed) {
        window.aplayers[i].destroy()
      }
    }
  }

  typeof typed === 'object' && typed.destroy()

  //reset readmode
  const $bodyClassList = document.body.classList
  $bodyClassList.contains('read-mode') && $bodyClassList.remove('read-mode')

  typeof disqusjs === 'object' && disqusjs.destroy()
})

document.addEventListener('pjax:complete', function () {
  window.refreshFn()

  document.querySelectorAll('script[data-pjax]').forEach(item => {
    const newScript = document.createElement('script')
    const content = item.text || item.textContent || item.innerHTML || ""
    Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
    newScript.appendChild(document.createTextNode(content))
    item.parentNode.replaceChild(newScript, item)
  })

  GLOBAL_CONFIG.islazyload && window.lazyLoadInstance.update()

  typeof chatBtnFn === 'function' && chatBtnFn()
  typeof panguInit === 'function' && panguInit()

  // google analytics
  typeof gtag === 'function' && gtag('config', '', {'page_path': window.location.pathname});

  // baidu analytics
  typeof _hmt === 'object' && _hmt.push(['_trackPageview',window.location.pathname]);

  typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()

  // prismjs
  typeof Prism === 'object' && Prism.highlightAll()

  typeof preloader === 'object' && preloader.endLoading()
})

document.addEventListener('pjax:error', (e) => {
  if (e.request.status === 404) {
    pjax.loadUrl('/404.html')
  }
})</script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div><!-- hexo injector body_end start --> <script data-pjax>if(document.getElementById('recent-posts') && (location.pathname ==='/'|| '/' ==='all')){
    var parent = document.getElementById('recent-posts');
    var child = '<div class="recent-post-item" style="width:100%;height: auto"><div id="catalog_magnet"><div class="magnet_item"><a class="magnet_link" href="https://www.naste.top:1024/categories/Java/"><div class="magnet_link_context" style=""><span style="font-weight:500;flex:1">🍡 XiaoFeiのJava学习笔记 (55)</span><span style="padding:0px 4px;border-radius: 8px;"><i class="fas fa-arrow-circle-right"></i></span></div></a></div><div class="magnet_item"><a class="magnet_link" href="https://www.naste.top:1024/categories/Linux/"><div class="magnet_link_context" style=""><span style="font-weight:500;flex:1">🍼 XiaoFeiのLinux笔记 (33)</span><span style="padding:0px 4px;border-radius: 8px;"><i class="fas fa-arrow-circle-right"></i></span></div></a></div><div class="magnet_item"><a class="magnet_link" href="https://www.naste.top:1024/categories/Python/"><div class="magnet_link_context" style=""><span style="font-weight:500;flex:1">🍉 XiaoFeiのPython笔记 (2)</span><span style="padding:0px 4px;border-radius: 8px;"><i class="fas fa-arrow-circle-right"></i></span></div></a></div><div class="magnet_item"><a class="magnet_link" href="https://www.naste.top:1024/categories/前端/"><div class="magnet_link_context" style=""><span style="font-weight:500;flex:1">🍟 XiaoFeiの前端笔记 (17)</span><span style="padding:0px 4px;border-radius: 8px;"><i class="fas fa-arrow-circle-right"></i></span></div></a></div><div class="magnet_item"><a class="magnet_link" href="https://www.naste.top:1024/categories/Other/"><div class="magnet_link_context" style=""><span style="font-weight:500;flex:1">🍥 XiaoFeiのOther笔记 (10)</span><span style="padding:0px 4px;border-radius: 8px;"><i class="fas fa-arrow-circle-right"></i></span></div></a></div><div class="magnet_item" style="visibility: hidden"></div><a class="magnet_link_more"  href="https://www.naste.top:1024/categories/" style="flex:1;text-align: center;margin-bottom: 10px;">查看更多...</a></div></div>';
    console.log('已挂载magnet')
    parent.insertAdjacentHTML("afterbegin",child)}
     </script><style>#catalog_magnet{flex-wrap: wrap;display: flex;width:100%;justify-content:space-between;padding: 10px 10px 0 10px;align-content: flex-start;}.magnet_item{flex-basis: calc(33.333333333333336% - 5px);background: #e9e9e9;margin-bottom: 10px;border-radius: 8px;transition: all 0.2s ease-in-out;}.magnet_item:hover{background: var(--text-bg-hover)}.magnet_link_more{color:#555}.magnet_link{color:black}.magnet_link:hover{color:white}@media screen and (max-width: 600px) {.magnet_item {flex-basis: 100%;}}.magnet_link_context{display:flex;padding: 10px;font-size:16px;transition: all 0.2s ease-in-out;}.magnet_link_context:hover{padding: 10px 20px;}</style>
    <style></style><script data-pjax>
  function butterfly_swiper_injector_config(){
    var parent_div_git = document.getElementById('recent-posts');
    var item_html = '<div class="recent-post-item" style="height: auto;width: 100%"><div class="blog-slider swiper-container-fade swiper-container-horizontal" id="swiper_container"><div class="blog-slider__wrp swiper-wrapper" style="transition-duration: 0ms;"><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/204253054.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://www.naste.top:9000/webp/1675912191.webp" alt="" onerror="this.src=https://unpkg.zhimg.com/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2023-03-08</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/204253054.html&quot;);" href="javascript:void(0);" alt="">SpringBoot使用实现定时任务和xxl-job实现分布式任务调度</a><div class="blog-slider__text">SpringBoot使用实现定时任务和xxl-job实现分布式任务调度</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/204253054.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/538133837.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://www.naste.top:9000/webp/1678672933.webp" alt="" onerror="this.src=https://unpkg.zhimg.com/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2023-03-15</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/538133837.html&quot;);" href="javascript:void(0);" alt="">Hexo中Markdown语法与外挂标签写法汇总</a><div class="blog-slider__text">Hexo中Markdown语法与外挂标签写法汇总</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/538133837.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div></div><div class="blog-slider__pagination swiper-pagination-clickable swiper-pagination-bullets"></div></div></div>';
    console.log('已挂载butterfly_swiper')
    parent_div_git.insertAdjacentHTML("afterbegin",item_html)
    }
  var elist = 'undefined'.split(',');
  var cpage = location.pathname;
  var epage = '/';
  var flag = 0;

  for (var i=0;i<elist.length;i++){
    if (cpage.includes(elist[i])){
      flag++;
    }
  }

  if ((epage ==='all')&&(flag == 0)){
    butterfly_swiper_injector_config();
  }
  else if (epage === cpage){
    butterfly_swiper_injector_config();
  }
  </script><script defer src="https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.js"></script><script defer data-pjax src="https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper_init.js"></script><div class="js-pjax"><script async="async">var arr = document.getElementsByClassName('recent-post-item');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__zoomIn');
    arr[i].setAttribute('data-wow-duration', '2s');
    arr[i].setAttribute('data-wow-delay', '200ms');
    arr[i].setAttribute('data-wow-offset', '30');
    arr[i].setAttribute('data-wow-iteration', '1');
  }</script><script async="async">var arr = document.getElementsByClassName('card-widget');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__zoomIn');
    arr[i].setAttribute('data-wow-duration', '2s');
    arr[i].setAttribute('data-wow-delay', '200ms');
    arr[i].setAttribute('data-wow-offset', '30');
    arr[i].setAttribute('data-wow-iteration', '1');
  }</script></div><script defer src="https://npm.elemecdn.com/hexo-butterfly-wowjs/lib/wow.min.js"></script><script defer src="https://npm.elemecdn.com/hexo-butterfly-wowjs/lib/wow_init.js"></script><script data-pjax src="https://npm.elemecdn.com/hexo-filter-gitcalendar/lib/gitcalendar.js"></script><script data-pjax>
  function gitcalendar_injector_config(){
      var parent_div_git = document.getElementById('gitZone');
      var item_html = '<div class="recent-post-item" id="gitcalendarBar" style="width:100%;height:auto;padding:10px;"><style>#git_container{min-height: 320px}@media screen and (max-width:650px) {#git_container{min-height: 0px}}</style><div id="git_loading" style="width:10%;height:100%;margin:0 auto;display: block;"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50" xml:space="preserve"><path fill="#d0d0d0" d="M25.251,6.461c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615V6.461z" transform="rotate(275.098 25 25)"><animatetransform attributeType="xml" attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="0.6s" repeatCount="indefinite"></animatetransform></path></svg><style>#git_container{display: none;}</style></div><div id="git_container"></div></div>';
      parent_div_git.insertAdjacentHTML("afterbegin",item_html)
      console.log('已挂载gitcalendar')
      }

    if( document.getElementById('gitZone') && (location.pathname ==='/personal/about/'|| '/personal/about/' ==='all')){
        gitcalendar_injector_config()
        GitCalendarInit("https://gitcalendar.naste.top/api?xiao-i-fei",['#d9e0df', '#c6e0dc', '#a8dcd4', '#9adcd2', '#89ded1', '#77e0d0', '#5fdecb', '#47dcc6', '#39dcc3', '#1fdabe', '#00dab9'],'xiao-i-fei')
    }
  </script><!-- hexo injector body_end end --></body></html>